-
-
Save YutaSeya/085a620cd2b5ac46354ff8a49616492b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <opencv2/opencv.hpp> | |
#include <iostream> | |
#include <cmath> | |
using namespace cv; | |
using namespace std; | |
#define PI 3.1415926535f | |
//#define _DEBUG | |
/** | |
* @brief 自作平均フィルタ | |
* @detail 端の計算処理はしていないため、端の画素は入力画像と同じように表示される。 | |
* 理想は、端のほうも処理をいれることだが、バグフィックスが面倒なためいれていない。 | |
**/ | |
Mat myAverageFilter(Mat data, Size ksize) | |
{ | |
int height = data.size().height; | |
int width = data.size().width; | |
Mat out; | |
out = data.clone(); | |
uint64_t sumR = 0; | |
uint64_t sumG = 0; | |
uint64_t sumB = 0; | |
for (int x = ksize.width/2; x < width- ksize.width/2; x++) { | |
for (int y = ksize.height/2; y < height-ksize.height/2; y++) { | |
for (int k = -ksize.width/2; k <= ksize.width / 2; k++) { | |
for (int l = -ksize.height/2; l <= ksize.height/2; l++) { | |
sumB += data.at<Vec3b>(y + l, x + k)[0]; | |
sumG += data.at<Vec3b>(y + l, x + k)[1]; | |
sumR += data.at<Vec3b>(y + l, x + k)[2]; | |
} | |
} | |
out.at<Vec3b>(y - ksize.height / 2, x - ksize.width / 2)[0] = sumB / ksize.area(); | |
out.at<Vec3b>(y - ksize.height / 2, x - ksize.width / 2)[1] = sumG / ksize.area(); | |
out.at<Vec3b>(y - ksize.height / 2, x - ksize.width / 2)[2] = sumR / ksize.area(); | |
sumB = 0; | |
sumG = 0; | |
sumR = 0; | |
} | |
} | |
return out; | |
} | |
/** | |
* @brief 自作ガウシアンフィルタ | |
* @detail 端の計算処理はしていないため、端の画素は入力画像と同じように表示される。 | |
* 理想は、端のほうも処理をいれることだが、バグフィックスが面倒なためいれていない。 | |
**/ | |
Mat myGaussianFilter(Mat data, Size ksize, float sigma) | |
{ | |
Mat karnel; | |
karnel = Mat::zeros(ksize, CV_32F); | |
float gause_sum = 0.0f; | |
// ガウシアンフィルタ用のカーネルを作成 | |
for (int x = -ksize.width/2; x <= ksize.width/2; x++) { | |
for (int y = -ksize.height/2; y <= ksize.height/2; y++) { | |
karnel.at<float>(y + ksize.height / 2, x + ksize.width / 2) = (float)exp(-((x * x + y * y) / (2 * sigma * sigma))) / (2 * PI * sigma * sigma); | |
gause_sum += karnel.at<float>(y + ksize.height / 2, x + ksize.width / 2); | |
} | |
} | |
// スカラ倍をして、和が1になるように落とし込む | |
karnel = karnel / gause_sum; | |
#if _DEBUG 1 | |
cout << karnel << endl; | |
#endif | |
int height = data.size().height; | |
int width = data.size().width; | |
Mat out; | |
out = data.clone(); | |
float sumR = 0; | |
float sumG = 0; | |
float sumB = 0; | |
for (int x = ksize.width / 2; x < width - ksize.width / 2; x++) { | |
for (int y = ksize.height / 2; y < height - ksize.height / 2; y++) { | |
for (int k = -ksize.width / 2; k <= ksize.width / 2; k++) { | |
for (int l = -ksize.height / 2; l <= ksize.height / 2; l++) { | |
sumB += (float)data.at<Vec3b>(y + l, x + k)[0] * karnel.at<float>(l + ksize.height / 2, k + ksize.width / 2); | |
sumG += (float)data.at<Vec3b>(y + l, x + k)[1] * karnel.at<float>(l + ksize.height / 2, k + ksize.width / 2); | |
sumR += (float)data.at<Vec3b>(y + l, x + k)[2] * karnel.at<float>(l + ksize.height / 2, k + ksize.width / 2); | |
} | |
} | |
out.at<Vec3b>(y - ksize.height / 2, x - ksize.width / 2)[0] = sumB; | |
out.at<Vec3b>(y - ksize.height / 2, x - ksize.width / 2)[1] = sumG; | |
out.at<Vec3b>(y - ksize.height / 2, x - ksize.width / 2)[2] = sumR; | |
sumB = 0.0f; | |
sumG = 0.0f; | |
sumR = 0.0f; | |
} | |
} | |
return out; | |
} | |
int main() | |
{ | |
Mat data; | |
Mat out; | |
data = imread("2.png"); | |
out = myGaussianFilter(data, Size(3, 3), 1.0); | |
imshow("my average filter", out); | |
waitKey(); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment