在我的Android应用中,我正在从后台服务程序中以编程方式捕获屏幕截图。 我将其作为
接下来,我使用以下Android框架API获取感兴趣区域(ROI)的坐标:
这里,
在 Android 中,
现在,在执行任何与OpenCV相关的操作之前,我们需要将Android
现在我正在执行的OpenCV操作之一是模糊截屏中的ROI。
这使我们非常接近所需的结果。接近了,但还不够。目标区域下方的区域模糊。例如,如果感兴趣的目标区域是密码字段,则上述代码会产生以下结果:左侧为Microsoft Live ROI,右侧为Pinterest ROI。
所以我的问题是,为什么感兴趣的确切区域没有被模糊?
通过Android API getBoundsInScreen()获取的坐标似乎是正确的。
将Android Rect转换为OpenCV Rect也似乎是正确的。还是有问题吗?
模糊感兴趣区域的代码似乎也是正确的。还有其他方法可以做同样的事情吗?
请注意:我提供了实际大小的屏幕截图,因为它们正在获取。它们已经缩小了50%以适应此帖子,但除此之外,它们与我在Android设备上获取的完全相同。
Bitmap
获取。接下来,我使用以下Android框架API获取感兴趣区域(ROI)的坐标:
Rect ROI = new Rect();
viewNode.getBoundsInScreen(ROI);
这里,
getBoundsInScreen()
是 Android 版本的 Javascript 函数 getBoundingClientRect()
。在 Android 中,
Rect
具有以下属性:rect.top
rect.left
rect.right
rect.bottom
rect.height()
rect.width()
rect.centerX() /* rounded off to integer */
rect.centerY()
rect.exactCenterX() /* exact value in float */
rect.exactCenterY()
而在OpenCV中,Rect
具有以下属性
rect.width
rect.height
rect.x /* x coordinate of the top-left corner */
rect.y /* y coordinate of the top-left corner */
现在,在执行任何与OpenCV相关的操作之前,我们需要将Android
Rect
转换为OpenCV Rect
。
有两种方法可以将Android
Rect
转换为OpenCV Rect
(如Karl Phillip在他的答案中建议的)。两种方法生成相同的值并产生相同的结果。/* Compute the top-left corner using the center point of the rectangle. */
int x = androidRect.centerX() - (androidRect.width() / 2);
int y = androidRect.centerY() - (androidRect.height() / 2);
// OR simply use the already available member variables:
x = androidRect.left;
y = androidRect.top;
int w = androidRect.width();
int h = androidRect.height();
org.opencv.core.Rect roi = new org.opencv.core.Rect(x, y, w, h);
现在我正在执行的OpenCV操作之一是模糊截屏中的ROI。
Mat originalMat = new Mat();
Bitmap configuredBitmap32 = originalBitmap.copy(Bitmap.Config.ARGB_8888, true);
Utils.bitmapToMat(configuredBitmap32, originalMat);
Mat ROIMat = originalMat.submat(roi).clone();
Imgproc.GaussianBlur(ROIMat, ROIMat, new org.opencv.core.Size(0, 0), 5, 5);
ROIMat.copyTo(originalMat.submat(roi));
Bitmap blurredBitmap = Bitmap.createBitmap(originalMat.cols(), originalMat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(originalMat, blurredBitmap);
这使我们非常接近所需的结果。接近了,但还不够。目标区域下方的区域模糊。例如,如果感兴趣的目标区域是密码字段,则上述代码会产生以下结果:左侧为Microsoft Live ROI,右侧为Pinterest ROI。
所以我的问题是,为什么感兴趣的确切区域没有被模糊?
通过Android API getBoundsInScreen()获取的坐标似乎是正确的。
将Android Rect转换为OpenCV Rect也似乎是正确的。还是有问题吗?
模糊感兴趣区域的代码似乎也是正确的。还有其他方法可以做同样的事情吗?
请注意:我提供了实际大小的屏幕截图,因为它们正在获取。它们已经缩小了50%以适应此帖子,但除此之外,它们与我在Android设备上获取的完全相同。