问题
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!
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/26822413/how-to-blur-a-rectagle-with-opencv