如何直接在原始图像的ROI部分进行图像处理操作?

时间:2015-10-09 04:01:51

标签: opencv image-processing

是否可以通过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中执行此操作吗?如果是的话,该怎么做?

3 个答案:

答案 0 :(得分:9)

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

Mat3b img = imread("path_to_image");

IMG:

enter image description here

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

只要您不更改图片类型,就可以使用roi3b。所有更改都将反映在原始图片img

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

模糊后的img:

enter image description here

如果您更改了类型(例如从CV_8UC3CV_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);

img after threshold:

enter image description here

完整的参考代码:

#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;
}

答案 1 :(得分:1)

要模糊所需区域,请执行以下步骤:

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()(范围rowRange,Range colRange)

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

答案 2 :(得分:1)

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

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;
}