【问题标题】:How can I do image processing operations only in ROI part of original image directly?如何直接在原始图像的 ROI 部分进行图像处理操作?
【发布时间】:2015-10-09 04:01:51
【问题描述】:

是否可以通过使用OpenCV只在原始图像的ROI部分进行一些图像处理操作?

我在互联网上搜索了一些文章。大多数代码如下所示:

int main(int argc, char** argv) {

    cv::Mat image;

    image = cv::imread(argv[1], CV_LOAD_IMAGE_COLOR);   
    cv::Rect roi( 100, 100,200, 200);

    //do some operations on roi

    cv::waitKey(0);
    return 0;
}

实际上,它创建了一个名为 roi 的新图像,然后在新创建的图像中进行一些操作。我想直接在原始图像中进行操作。比如我想做高斯模糊,只模糊原图中roi部分的范围,不模糊这张图的其他部分。

因为新创建的图像 roi 与原始图像中的信息具有不同的信息。 (比如坐标)我想保留这些信息。

在 OpenCV 中可以做到这一点吗?如果有,该怎么做?

【问题讨论】:

    标签: opencv image-processing


    【解决方案1】:

    您可以使用一个Rect 或两个Range 获取子图像(请参阅OpenCV doc)。

    Mat3b img = imread("path_to_image");
    

    图片:

    Rect r(100,100,200,200);
    Mat3b roi3b(img(r));
    

    只要不更改图像类型,您就可以使用roi3b。所有的变化都会反映在原图img

    GaussianBlur(roi3b, roi3b, Size(), 10);
    

    模糊后的图像:

    如果您更改类型(例如,从 CV_8UC3 更改为 CV_8UC1),您需要处理深层副本,因为 Mat 不能有混合类型。

    Mat1b roiGray;
    cvtColor(roi3b, roiGray, COLOR_BGR2GRAY);
    threshold(roiGray, roiGray, 200, 255, THRESH_BINARY);
    

    您始终可以将结果复制到原始图像上,注意纠正类型:

    Mat3b roiGray3b;
    cvtColor(roiGray, roiGray3b, COLOR_GRAY2BGR);
    roiGray3b.copyTo(roi3b);
    

    阈值后的图像:

    完整代码供参考:

    #include <opencv2\opencv.hpp>
    using namespace cv;
    
    int main(void)
    {
        Mat3b img = imread("path_to_image");
    
        imshow("Original", img);
        waitKey();
    
        Rect r(100,100,200,200);
        Mat3b roi3b(img(r));
    
        GaussianBlur(roi3b, roi3b, Size(), 10);
    
        imshow("After Blur", img);
        waitKey();
    
        Mat1b roiGray;
        cvtColor(roi3b, roiGray, COLOR_BGR2GRAY);
    
        threshold(roiGray, roiGray, 200, 255, THRESH_BINARY);
    
        Mat3b roiGray3b;
        cvtColor(roiGray, roiGray3b, COLOR_GRAY2BGR);
        roiGray3b.copyTo(roi3b);
    
        imshow("After Threshold", img);
        waitKey();
    
        return 0;
    }
    

    【讨论】:

    • 你在思考和表达方面真的很经典。
    【解决方案2】:

    要模糊所需区域,请按照以下步骤操作:

    cv::Rect roi(x, y, w, h);
    cv::GaussianBlur(image(roi), image(roi), Size(0, 0), 4); 
    

    点击此链接了解更多信息http://docs.opencv.org/modules/core/doc/basic_structures.html#id6

    Mat::operator()(Range rowRange, Range colRange)

    Mat::operator()(const Rect& roi)

    【讨论】:

    • 如果我想进一步处理,比如 ROI 中的 Canny 边缘检测。在我检测到边缘后,最终结果无法在原始图像上显示。 cv::矩形 roi(x, y, w, h); cv::GaussianBlur(图像(roi), 图像(roi), 大小(0, 0), 4); cv::Canny(图像(roi), 图像(roi),50, 100); imshow("图片",图片);
    • 接受对您有帮助的答案。使用上面的代码。并按照链接将图像放置到原始图像按照此链接相同stackoverflow.com/questions/10481411/…
    【解决方案3】:

    我已经对感兴趣区域进行了毛刺,并对模糊区域进行了分割,您可以对原始图像中的模糊区域进行图像处理操作,也可以对分割区域进行处理。

    int main() {
    
        Mat image;
        image=imread("Light.jpg",1);
    
       // image = cv::imread(argv[1], CV_LOAD_IMAGE_COLOR);   
        Rect roi( 100, 100,200, 200);
        Mat blur;
        GaussianBlur(image(roi), blur, Size(0, 0), 4); 
        imshow("blurred region",blur);
        //do some operations on roi
        imshow("aaaa",image);
        waitKey(0);
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-14
      • 2018-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多