2014-06-12 217 views
9

是否可以仅使用OpenCV模糊图像的子区域而不是整个图像来节省一些计算成本?高斯模糊与OpenCV:只模糊图像的子区域?

谢谢!

编辑:重要的一点是,当模糊分区域的边界时,应尽可能使用现有的图像内容;只有当卷积超过原始图像的边界时,才可以使用外推或其他人造边界条件。

回答

10

模糊的整体形象,假设你想覆盖原来的(就地过滤支持cv::GaussianBlur),您将有类似

cv::GaussianBlur(image, image, Size(0, 0), 4); 

要只是一个模糊区域使用Mat::operator()(const Rect& roi)提取区域:

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

或者,如果你想在一个单独的图像模糊输出:

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

上面使用的默认BORDER_CONSTANT选项只是假定在图像外面的所有内容都是0。 我不确定它是如何处理区域边缘的像素。您可以强制它忽略区域外的像素(BORDER_CONSTANT | BORDER_ISOLATE)。所以它认为它可能确实使用区域外的像素。你需要比较上面的结果:

const int bsize = 10; 
cv::Rect region(x, y, w, h); 
cv::Rect padded_region(x - bsize, y - bsize, w + 2 * bsize, h + 2 * bsize) 
cv::Mat blurred_padded_region; 
cv::GaussianBlur(image(padded_region), blurred_padded_region, Size(0, 0), 4); 

cv::Mat blurred_region = blurred_padded_region(cv::Rect(bsize, bsize, w, h)); 
// and you can then copy that back into the original image if you want: 
blurred_region.copyTo(image(region)); 
+0

似乎这种方法不关心的边界 - 它仍然使用某种插值而不是区域外的图像。我对吗? – xuhdev

+0

@xuhdev你是对的。我已经添加了一个例子来解决这个问题。如果该区域可能接近一个或两个包含图像的边界,则需要添加一些混乱来应对。 – Bull

+0

@xuhdev,看着过滤器引擎代码,我现在认为你可能不对。需要测试。 – Bull

3

是的,可以模糊OpenCV中的感兴趣区域。

size(120, 160); 
OpenCV opencv = new OpenCV(this); 
opencv.loadImage("myPicture.jpg"); 
opencv.ROI(60, 0, 60, 160); 
opencv.blur(OpenCV.BLUR, 13); 
image(opencv.image(), 0, 0); 

欲了解更多信息,请查看link。 祝你好运,

+0

顺便说一句,这个问题有一个C++标记。 C++解决方案的形式与Java的形式完全不同。 – Bull

+0

@B ...对我来说没关系。从一种语言翻译到另一种语言很容易。 – xuhdev

+0

一开始没有注意到,但很高兴我能帮到 –