もともと色々な処理できる関数が用意されているけど、OpenCVでモザイク処理ってやってなかったなーって思ったので書いてみた。
画像全体でもいいけどどうせだったら顔認識した部分限定でかけたいとかあると思うのでROIとなる引数をとるstaticメソッド。
/**
* ROIを指定してモザイク処理
* @param image 元画像となる {@link Mat}
* @param rectangles モザイク対象のROIを指定した {@link MatOfRect}
* @param size モザイクのピクセル幅
* @return モザイク処理後の {@link Mat}
*/
public static Mat drawMosaic(Mat image, MatOfRect rectangles, int size) {
Mat dstImage = image.clone();
for (Rect rect : rectangles.toArray()) {
Mat imageROI = new Mat(image, rect);
Mat dstImageROI = new Mat(dstImage, rect);
for (int y = 0; y < imageROI.height(); y += size) {
for (int x = 0; x < imageROI.width(); x += size) {
int yLimit = y + size;
if (yLimit >= imageROI.height()) {
yLimit = imageROI.height();
}
int xLimit = x + size;
if (xLimit >= imageROI.width()) {
xLimit = imageROI.width();
}
double b, g, r;
b = g = r = 0;
int winSize = 0;
for (int i = y; i < yLimit; i++) {
for (int j = x; j < xLimit; j++) {
double[] pixel = imageROI.get(j, i);
b += pixel[0];
g += pixel[1];
r += pixel[2];
winSize++;
}
}
b /= winSize;
g /= winSize;
r /= winSize;
for (int i = y; i < yLimit; i++) {
for (int j = x; j < xLimit; j++) {
dstImageROI.put(j, i, new double[] { b, g, r });
}
}
}
}
}
return dstImage;
}