如何直接在原始图像的ROI部分进行图像处理操作? [英] How can I do image processing operations only in ROI part of original image directly?

查看:119
本文介绍了如何直接在原始图像的ROI部分进行图像处理操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

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

cv :: Mat图像;

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

//在roi上做一些操作

cv :: waitKey(0);
返回0;
}

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



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



这是否可以在OpenCV中执行此操作?如果是这样,该怎么办?

解决方案

你可以使用获取子图像Rect 或两个 Range (参见OpenCV

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

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

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

模糊后的img:





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

img after threshold:





完整代码供参考:

  #include< opencv2 \opencv.hpp> 
使用命名空间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();

返回0;
}


Is that possible by using OpenCV to do some image processing operations only in ROI part of original image?

I search some articles on Internet. Most of codes look like this:

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

Actually, it created a new image called roi, and then do some operations in new created image. I want to do operations in original image directly. For example, I want to do gaussian blur, only blur the range of roi part in original image and do not blur other part of this image.

Because new created image roi has different informations with its information in original image. (like coordinates) I want to keep those information.

Is that possible to do this in OpenCV? If so, how to do it?

解决方案

You can get the sub-image using one either a Rect or two Range (see OpenCV doc).

Mat3b img = imread("path_to_image");

img:

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

As long as you don't change image type you can work on roi3b. All changes will be reflected in the original image img:

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

img after blur:

If you change type (e.g. from CV_8UC3 to CV_8UC1), you need to work on a deep copy, since a Mat can't have mixed types.

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

You can always copy the results on the original image, taking care to correct the type:

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

img after threshold:

Full code for reference:

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

这篇关于如何直接在原始图像的ROI部分进行图像处理操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆