在Android上模糊图像中的区域(使用Java) [英] Blurring a region in an image on Android (in Java)

查看:124
本文介绍了在Android上模糊图像中的区域(使用Java)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Android应用中,我正在以编程方式从后台服务捕获屏幕截图.我以Bitmap的形式获得它.

In my Android app, I am capturing a screenshot programmatically from a background service. I obtain it as a Bitmap.

接下来,我使用以下Android框架API获取感兴趣区域(ROI)的坐标:

Next, I obtain the co-ordinates of a region of interest (ROI) with the following Android framework API:

Rect ROI = new Rect();
viewNode.getBoundsInScreen(ROI);

在这里 getBoundsInScreen() 与Javascript函数 getBoundingClientRect() .

Android中的 Rect 具有以下属性:

A Rect in Android has the following properties:

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()

Android Rect中顶部,左侧,右侧和底部的含义是什么 对象

What does top, left, right and bottom mean in Android Rect object

而OpenCV中的 Rect 具有以下属性

Whereas a Rect in OpenCV has the following properties

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.

Now before we can perform any OpenCV-related operations, we need to transform the Android Rect to an OpenCV Rect.

了解drawRect或绘图坐标在Android中的实际工作方式

有两种方法可以将Android Rect转换为OpenCV Rect(如 Karl Phillip 所建议的那样)在他的回答中).两者都产生相同的值,并且都产生相同的结果:

There are two ways to convert an Android Rect to an OpenCV Rect (as suggested by Karl Phillip in his answer). Both generate the same values and both produce the same result:

/* 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 :

Now one of the OpenCV operations I am performing is blurring the ROI within the screenshot:

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

这使我们非常接近期望的结果.快到了,但是没有 相当. 目标区域下方的区域是模糊的.

This brings us very close to the desired result. Almost there, but not quite. The area just BENEATH the targeted region is blurred.

例如,如果目标兴趣区域是密码字段,则上面的代码将产生以下结果:

For example, if the targeted region of interest is a password field, the above code produces the following results:

在左侧, Microsoft Live ROI ,在右侧, Pinterest ROI :

可以看出,ROI下方 的区域变得模糊了.

As can be seen, the area just below the ROI gets blurred.

所以我的问题是,最后,为什么不是确切的关注区域 模糊吗?

So my question is, finally, why isn't the exact region of interest blurred?

  • 通过Android API getBoundsInScreen()获得的坐标似乎正确.
  • 将Android Rect转换为OpenCV Rect似乎也是正确的.是吗?
  • 用于模糊感兴趣区域的代码似乎也是正确的.还有另一种方法可以做同样的事情吗?
  • The co-ordinates obtained through the Android API getBoundsInScreen() appear to be correct.
  • Converting an Android Rect to an OpenCV Rect also appears to be correct. Or is it?
  • The code for blurring a region of interest also appears to be correct. Is there another way to do the same thing?

NB:我已经提供了实际的全尺寸屏幕截图.它们已按比例缩小了50%以适合本文,但除此之外,它们与我在Android设备上获得的完全一样.

N.B: I've provided the actual, full-size screenshots as I am getting them. They have been scaled down by 50% to fit in this post, but other than that they are exactly as I am getting them on the Android device.

推荐答案

如果我没记错的话,OpenCV的Rect假定xy指定矩形的左上角:

If I'm not mistaken, OpenCV's Rect assumes that x and y specify the top left corner of the rectangle:

/* 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);

这篇关于在Android上模糊图像中的区域(使用Java)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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