OpenCV 中的缩放功能 imshow Windows

Zooming functionality in OpenCV imshow in Windows

在 Ubuntu 中,OpenCV 的 imshow 函数有一个 window 可以使用不同的选项,例如放大、缩小、平移 window 等,如下所示:

但是,Windows 中没有这些功能。我有一个特殊情况,我需要在 Windows 上部署我的 OpenCV 代码,用户需要放大图像的某些部分。

有什么方法可以在 Windows 中 access/add 这些功能吗?

https://gist.github.com/BartG95/1ce8ba1e9c25ec3698d1

似乎是一个较长的过程,因此您可以改用 matplotlib 的 pyplot 函数(使用 Qt)。你需要先涂上这个内衬(详情见Extracting a region from an image using slicing in Python, OpenCV):

import cv2
import matplotlib.pyplot as plt

image = cv2.imread("~\imagedir\image.jpg")
plt_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
imgplot = plt.imshow(plt_image)

绕路,PIL:

import cv2
from PIL import Image

img = cv2.imread('lena.jpg')
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
im_pil = Image.fromarray(img2)
im_pil.show()

基本思想是决定每次鼠标滚轮改变的比例。

获取当前比例(v.s.原始图像)和正确的图像显示区域后,就可以得到缩放图像上矩形的位置和长度。

所以你可以在缩放后的图像上绘制这个矩形。

在我的github中,查看class COpenCVWindowExt是如何实现的,更重要的是,这个项目可以缩放in/out和平移图像仅使用 opencv window.

虽然是c++代码,只需要将imshow()和resize()改成python版本就可以了

效果:

部分代码:

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;

    }
}

@mluerig 和许多其他人指出了解决方案 - 在 cmake 中启用 QT。我在这里分享原因和我的解决方案。

原因:

如果你去the highgui module documentation,我们会发现那些功能,比如缩放,像素值只能用Qt GUI实现。

我的解决方案:

  1. 如果您像我一样想要使用 CUDA 支持和其他额外模块,则必须在启用 Qt 的情况下从源代码构建。

  2. 如果您对 CUDA 不感兴趣,但想学习一些额外的模块,您可以使用:conda install libopencv opencv py-opencv 可选:(--channel conda-forge)

  3. 如果您只想要主要模块:conda install -c conda-forge opencv 任何使用 pip 的安装都不适合我。