在屏幕截图中模糊矩形

Posted

技术标签:

【中文标题】在屏幕截图中模糊矩形【英文标题】:Blurring a Rect within a screenshot 【发布时间】:2020-05-14 22:22:05 【问题描述】:

我正在开发一个 android 应用程序,它使用背景 Service 以编程方式捕获当前屏幕上的任何内容的屏幕截图。我以Bitmap 获取屏幕截图。

接下来,我成功地将OpenCV导入到我的Android项目中。

我现在需要做的是模糊该图像的 子集,即不是整个图像本身,而是图像中的 [矩形] 区域或子区域。我有一个 Rect 对象数组,代表我需要在屏幕截图中模糊的矩形区域。

我一直在寻找有关在 Java 中使用 OpenCV 执行此操作的教程,但我还没有找到明确的答案。 MatImgproc 类显然是令人感兴趣的,还有 Mat.submat() 方法,但我一直无法找到一个清晰、直接的教程来完成这项工作。

我搜索了很多,但我找到的示例都不完整。我需要在 Java 中,在 Android 运行时中执行此操作。

我需要的是:Bitmap >>> Mat >>> Imgproc>>> Rect >>> Bitmap 与 ROI 模糊。

这里有经验丰富的 OpenCV 开发人员,您能指出我正确的方向吗?这是我唯一坚持的事情。

相关

Gaussian blurring with OpenCV: only blurring a subregion of an image?.

How to blur a rectagle with OpenCv.

How to blur some portion of Image in Android?.

【问题讨论】:

简单来说,您可以将 ROI 提取到单独的 Mat 中,将过滤应用到该 Mat 并将其重新插入到原始图像中。还是我在这里遗漏了什么? 我想我错过了一些东西,因为这个问题对我来说似乎很简单!在 c++ 中,如果 img 是你的 Mat 而 r 是你的 Rect,那么 img(r) 本身就是一个图像,你可以将它独立地提供给 blur 函数 => blur(img(r), img(r), ksize); 【参考方案1】:

实现此任务的 C++ 代码在下面与 cmets 和示例图像共享:

// load an input image
Mat img = imread("C:\\elon_tusk.png");

img

// extract subimage
Rect roi(113, 87, 100, 50);
Mat subimg = img(roi);

subimg

// blur the subimage
Mat blurred_subimage;
GaussianBlur(subimg, blurred_subimage, Size(0, 0), 5, 5);

blurred_subimage

// copy the blurred subimage back to the original image
blurred_subimage.copyTo(img(roi));

img

Android 等效项:

Mat img = Imgcodecs.imread("elon_tusk.png");
Rect roi = new Rect(113, 87, 100, 50);
Mat subimage = img.submat(roi).clone();
Imgproc.GaussianBlur(subimg, subimg, new Size(0,0), 5, 5);
subimg.copyTo(img.submat(roi));

【讨论】:

这有点像我写的,但我还是给了你一个赞成票,以获得更详细的答案! 用 Android 代码更新了答案。不知道是否有效,但无法测试。 Look at this file 了解如何从 OpenCV 导入内容。 完美的输入图像选择 @karlphillip:感谢您不厌其烦。您的代码很可能是正确答案。试用后会报告... ;) 我认为你不需要复制 roi。据我记得 Mat subimage = img.submat(roi) 应该创建一个指向原始图像区域的指针。如果你模糊子图像,你会自动模糊原始图像(如果你不克隆它)。【参考方案2】:

您可以只实现自己的辅助函数,我们称之为 roi(感兴趣区域)。 由于 opencv 中的图像是 numpy ndarrays,你可以这样做:

def roi(image: np.ndarray, region: QRect) -> np.ndarray:
    a1 = region.upperLeft().x()
    b1 = region.bottomRight().y()
    a2 = region.upperLeft().x()
    b2 = region.bottomRight().y()
    return image[a1:a2, b1:b2]

只需使用此辅助函数提取您感兴趣的图像的子区域,将它们模糊并将结果放回原始图片上。

【讨论】:

以上是关于在屏幕截图中模糊矩形的主要内容,如果未能解决你的问题,请参考以下文章

屏幕截图程序在截图后留下正方形

如何禁用屏幕截图或模糊内容是 iOS 之类的 ScreenShieldKit?

视图的屏幕截图与视图的大小不同?

功能齐全的屏幕截图C++实现详解

功能齐全的屏幕截图C++实现详解

怎么把截图调清晰