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