在我的 Android 应用程序中,我从后台服务以编程方式捕获屏幕截图。我以Bitmap.
接下来,我使用以下 Android 框架 API 获取感兴趣区域 (ROI) 的坐标:
Rect ROI = new Rect();
viewNode.getBoundsInScreen(ROI);
Run Code Online (Sandbox Code Playgroud)
这里,getBoundsInScreen()是 Javascript 函数的 Android 等价物getBoundingClientRect()。
RectAndroid 中的A具有以下属性:
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()
Run Code Online (Sandbox Code Playgroud)
而RectOpenCV 中的a具有以下属性
rect.width
rect.height
rect.x /* x coordinate of the top-left corner */
rect.y /* y coordinate of the top-left corner */
Run Code Online (Sandbox Code Playgroud)
现在,在我们可以执行任何与 OpenCV 相关的操作之前,我们需要将 AndroidRect转换为 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);
Run Code Online (Sandbox Code Playgroud)
现在我正在执行的 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);
Run Code Online (Sandbox Code Playgroud)
这使我们非常接近预期的结果。几乎在那里,但不完全。目标区域正下方的区域是模糊的。
例如,如果目标感兴趣区域是密码字段,则上述代码会产生以下结果:
左侧是Microsoft Live ROI,右侧是Pinterest ROI:
可以看出,ROI正下方的区域变得模糊。
所以我的问题是,最后,为什么感兴趣的确切区域没有模糊?
- 通过 Android API 获得的坐标
getBoundsInScreen()似乎是正确的。- 将 Android
Rect转换为 OpenCVRect似乎也是正确的。或者是吗?- 用于模糊感兴趣区域的代码似乎也是正确的。有没有另一种方法可以做同样的事情?
注意:我已经提供了实际的全尺寸屏幕截图。它们已经缩小了 50% 以适应这篇文章,但除此之外,它们与我在 Android 设备上得到的完全一样。
如果我没记错的话,OpenCVRect会假设x并y指定矩形的左上角:
/* Compute the top-left corner using the center point of the rectangle
* TODO: take care of float to int conversion
*/
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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
301 次 |
| 最近记录: |