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;
}
原图:
效果图: