1

Is there any way to blur a Mat object in OpenCv (for Android) so that the blur is contained within a Rect object? I am doing a face blurring application and have tried this:

Mat mat = ...; // is initialized properly to 480*640

...

Mat blurred = new Mat();
for (Rect rect : faceDetections.toArray()) {
  int xStart = Math.max(0, rect.x);
  int yStart = Math.max(0, rect.y);

  Imgproc.blur(mat, blurred, new Size(rect.width/2, rect.height/2), new Point(xStart, yStart));

  Core.rectangle(blurred, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
  new Scalar(0, 255, 0));
}

If I comment out the Imgproc.blur part then it works correctly by drawing a rectagle around the face. However, when I run it with this line I get the following in the logs:

11-07 17:27:54.100: E/AndroidRuntime(25665): Caused by: CvException [org.opencv.core.CvException: cv::Exception: /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/imgproc/src/filter.cpp:182: error: (-215) 0 <= anchor.x && anchor.x < ksize.width && 0 <= anchor.y && anchor.y < ksize.height in function void cv::FilterEngine::init(const cv::Ptr<cv::BaseFilter>&, const cv::Ptr<cv::BaseRowFilter>&, const cv::Ptr<cv::BaseColumnFilter>&, int, int, int, int, int, const Scalar&)

This means that the anchor point is out of bounds, but I have looked up that the (0,0) point for open CV is the upper left point so I don't think it should be going out of bounds.

Also ideally I would like to do a gaussian blur (instead of just blur) in the region, but I can't figure out how to bound that in the rectangle either: it always blurs the whole image.

Link to ImgProc docs. Any help is greatly appreciated!

nmore
  • 2,474
  • 1
  • 14
  • 21
  • 1
    Have you tried calling the function without setting the anchor? By default it puts it in the kernel center which might suit your case better. – VAndrei Nov 08 '14 at 21:50

2 Answers2

3

Ok I figured out how to do it:

Mat mask = blurred.submat(rect);
Imgproc.GaussianBlur(mask, mask, new Size(55, 55), 55); // or any other processing

Then blurred will have the blurred region. This is because submat doesn't copy the data in blurred, but rather references it, so when the blur is applied it only blurs the parts in blurred referenced by mask.

nmore
  • 2,474
  • 1
  • 14
  • 21
  • Hi! can you update your question or edit this answer with the fullcode? I can't manage to blur a face. i still have your same error – Frank Mar 19 '21 at 14:40
0

I'm not an expert but I think you are applying a filter with k size so actually k x k pixels with k odd (3x3, 5x5 etc). When you try to position yourself in the (0,0) the bound of the filter excees, because the filter maps it's center in the (0,0) pixel. If you k is 3 for example you need to start in the (2,2). And if you want a gaussian bidimensional filter remember to apply it one time in the x direction and one time in the y direction instead one time in the (x.y). This is for a performance reason.

Francesco
  • 131
  • 1
  • 4