The basic idea is deciding the scale changed every time on mouse wheel.
After you get the current scale (v.s. origin image) and correct region of image you want to show on screen, you can get the position and length of rectangle on scaled image.
So you can draw this rectangle on scaled image.
In my github,check how the class COpenCVWindowExt is implemented, more importantly, this project can zoom in/out and pan image only using opencv window.
Although it's c++ code, you only need to transform imshow () and resize () to python version.
Effect:

Part of the code:
void MouseCall (int event, int x, int y, int flag, void* pUserData)
{
COpenCVWindowExt* pParent = (COpenCVWindowExt*)pUserData;
if (event == EVENT_MOUSEWHEEL)
{
if (getMouseWheelDelta (flag) > 0 && pParent->m_iScaleTimes != pParent->m_iMaxScaleTimes)
pParent->m_iScaleTimes++;
else if (getMouseWheelDelta (flag) < 0 && pParent->m_iScaleTimes != pParent->m_iMinScaleTimes)
pParent->m_iScaleTimes--;
if (pParent->m_iScaleTimes == 0)
pParent->m_dCompensationX = pParent->m_dCompensationY = 0;
//Pixel value = mouse offset (v.s. window's left top position)
//But using x, y is not correct in Wheel Event. So, use pre recorded value
x = pParent->m_iMouseX;
y = pParent->m_iMouseY;
double dPixelX = (pParent->m_iHorzScrollBarPos + x + pParent->m_dCompensationX) / pParent->m_dNewScale;
double dPixelY = (pParent->m_iVertScrollBarPos + y + pParent->m_dCompensationY) / pParent->m_dNewScale;
pParent->m_dNewScale = pParent->m_dInitialScale * pow (pParent->m_dScaleRatio, pParent->m_iScaleTimes);
if (pParent->m_iScaleTimes != 0)
{
int iWidth = pParent->m_matSrc.cols;
int iHeight = pParent->m_matSrc.rows;
pParent->m_iHorzScrollBarRange_Max = int (pParent->m_dNewScale * iWidth - pParent->m_dInitialScale * iWidth) - 1;
pParent->m_iVertScrollBarRange_Max = int (pParent->m_dNewScale * iHeight - pParent->m_dInitialScale * iHeight) - 1;
int iBarPosX = pParent->m_iHorzScrollBarPos = int (dPixelX * pParent->m_dNewScale - x + 0.5);
int iBarPosY = pParent->m_iVertScrollBarPos = int (dPixelY * pParent->m_dNewScale - y + 0.5);
pParent->m_dCompensationX = -iBarPosX + (dPixelX * pParent->m_dNewScale - x);
pParent->m_dCompensationY = -iBarPosY + (dPixelY * pParent->m_dNewScale - y);
}
else
{
pParent->m_iHorzScrollBarPos = 0;
pParent->m_iVertScrollBarPos = 0;
}
pParent->RefreshImage ();
}
else if (event == EVENT_MOUSEMOVE)
{
pParent->m_iMouseX = x;
pParent->m_iMouseY = y;
}
}