Skip to content

Instantly share code, notes, and snippets.

@YutaSeya
Created January 8, 2020 03:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YutaSeya/085a620cd2b5ac46354ff8a49616492b to your computer and use it in GitHub Desktop.
Save YutaSeya/085a620cd2b5ac46354ff8a49616492b to your computer and use it in GitHub Desktop.
#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