首页 > 解决方案 > OpenCV,通过引用传递 Mat,并改变它的类型

问题描述

我想出了那个代码,用于旋转图像而不裁剪它们。它只是改变目标图像的大小,以避免角落被切掉:

实际rotate.cpp代码:

    int diagonal = (int)sqrt(src.cols*src.cols+src.rows*src.rows);
    int newWidth = diagonal;
    int newHeight = diagonal;
    cv::Mat container = cv::Mat::zeros(newWidth, newHeight, src.type());
    int offsetX = (newWidth - src.cols) / 2;
    int offsetY = (newHeight - src.rows) / 2;

    src.copyTo(container.rowRange(offsetY, offsetY + src.rows).colRange(offsetX, offsetX + src.cols));

    dst = container.clone();

    float rads = angle*3.1415926/180.0;
    float _cos = cos(-rads);
    float _sin = sin(-rads);
    float xcenter = (float)(container.cols)/2.0;
    float ycenter = (float)(container.rows)/2.0;

    for(int i = 0; i < container.rows; i++)
        for(int j = 0; j < container.cols; j++){

            int x = ycenter + ((float)(i)-ycenter)*_cos - ((float)(j)-xcenter)*_sin;
            int y = xcenter + ((float)(i)-ycenter)*_sin + ((float)(j)-xcenter)*_cos;

            if (x >= 0 && x < container.rows && y >= 0 && y < container.cols) {
                for (int k = 0; k < 4; k++)
                    dst.at<cv::Vec4b>(i,j)[k] = container.at<cv::Vec4b>(x, y)[k];
                  }

            else {
                dst.at<cv::Vec4b>(i,j)[3] = 0;
            }
        }

    cv::imshow("dst", dst);

最后的imshow函数仅用于检查结果,并且根据此屏幕截图(忽略颜色差异,Qt 读取RGBA, imshowin BGR):

屏幕

如您所见,我的应用程序中的 Label 似乎没有受到影响,从与 label 相同imshow的函数运行(每当从通知时启动),并且从函数内部启动正确显示旋转图片。updateUiupdateUiobservermodelimshowRotation

现在,在达到这一点之前,我的算法是:

    float rads = angle*3.1415926/180.0;
    float _cos = cos(-rads);
    float _sin = sin(-rads);
    float xcenter = (float)(src.cols)/2.0;
    float ycenter = (float)(src.rows)/

    for(int i = 0; i < src.rows; i++)
        for(int j = 0; j < src.cols; j++){

            int x = ycenter + ((float)(i)-ycenter)*_cos - ((float)(j)-xcenter)*_sin;
            int y = xcenter + ((float)(i)-ycenter)*_sin + ((float)(j)-xcenter)*_cos;
            if (x >= 0 && x < src.rows && y >= 0 && y < src.cols) {
                    dst.at<cv::Vec4b>(i,j) = src.at<cv::Vec4b>(x, y);
                  }
            else {
                dst.at<cv::Vec4b>(i,j)[3] = 0;
            }

它完美地显示在我的 Qt 标签上(当然,角落除外)。现在,我的想法是,有一些奇怪的事情发生在

...code...
dst = container.clone();
...code...

我已经尝试了不同的更改,例如使用另一个 Mat obj,最后制作

rotatedMat.copyTo(dst);
or...
dst = rotatedMat.clone();

但似乎我的dst垫子在模型中没有改变。当然,我通过引用我的所有函数来传递我的src和。dst

标签: c++imageqtopencvimage-processing

解决方案


经过一些测试,似乎 Mat objs 上的每个调整大小/克隆/复制功能,在克隆/复制之前释放内存.../...这就是为什么对 DST 的引用无效。解决方法:只需在函数调用之外调整 dst 矩阵的大小。


推荐阅读