Opencv之图像碎片滤镜

1.介绍

    原理很简单,一句话搞定: 以每个像素为中心,其余4个偏移分别以中心对称,斜45度均匀圆周布置,水平和垂直偏移各45度,偏移量4个像素。比如下面的图中,小A是由A移动得到的,其中在水平上,小A与小A的距离是8个像素,垂直方向上也是一样的。

2.代码

#include<opencv2\opencv.hpp>
#include<iostream>
#include<vector>

using namespace std;
using namespace cv;

void fragmentTrans(const Mat& src, Mat& dst) {
	int OffsetX[4] = { 4, -4, -4, 4 };                      // 每个点的偏移量
	int OffsetY[4] = { -4, -4, 4, 4 };

	int width = src.cols;
	int high = src.rows;
	int hh = 0;
	int ww = 0;
	for (int h = 0; h < high; ++h) {
		for (int w = 0; w < width; ++w) {
			int SumB = 0, SumG = 0, SumR = 0;
			for (int z = 0; z < 4; ++z) {
				ww = w + OffsetX[z];
				hh = h + OffsetY[z];
				if (ww < 0)                                                    //   注意越界
					ww = 0;
				else if (ww >= width)
					ww = width - 1;
				if (hh < 0)
					hh = 0;
				else if (hh >= high)
					hh = high - 1;
				SumB += src.at<Vec3b>(hh, ww)[0];
				SumG += src.at<Vec3b>(hh, ww)[1];
				SumR += src.at<Vec3b>(hh, ww)[2];
			}
			dst.at<Vec3b>(h, w)[0] = int((SumB + 2) >> 2);
			dst.at<Vec3b>(h, w)[1] = int((SumG + 2) >> 2);
			dst.at<Vec3b>(h, w)[2] = int((SumR + 2) >> 2);
		} 
	}
}

int main() {
	Mat src = imread("test.png");
	Mat dst = Mat::zeros(src.size(), src.type());
	fragmentTrans(src, dst);

	imshow("src", src);
	imshow("dst", dst);
	waitKey();
	return 0;
}

原图:

效果图:

3.参考资料

    https://www.cnblogs.com/Imageshop/p/3173090.html

发布了138 篇原创文章 · 获赞 141 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/u013289254/article/details/102845618