-
-
Save YutaSeya/05b52dc8fe3328c13e98bb7ea89f7039 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> | |
#include "myfilter.h" | |
using namespace cv; | |
using namespace std; | |
//#define __CHECK_OPENCV | |
//#define __CHECK_AVERAGE | |
//#define __CHECK_GAUSSIAN | |
#define __CHECK_SOBEL | |
#define __CHECK_LAPLACIAN | |
int main() | |
{ | |
Mat data; | |
data = imread("3.jpg"); | |
imshow("read data", data); | |
#if __CHECK_AVERAGE 1 | |
Mat ave; | |
ave = myAverageFilter(data, Size(3, 3)); | |
imshow("my average filter", ave); | |
#endif | |
#if __CHECK_GAUSSIAN 1 | |
Mat gauss; | |
gauss = myGaussianFilter(data, Size(3, 3), 1.2); | |
imshow("my gaussian filter", gauss); | |
#endif | |
#if __CHECK_SOBEL 1 | |
Mat sobel_h, sobel_v; | |
sobel_h = mySobelFilter(data, 0, 1); | |
sobel_v = mySobelFilter(data, 1, 1); | |
imshow("my sobel horizontal", sobel_h); | |
imshow("my sobel vertical", sobel_v); | |
#endif | |
#if __CHECK_LAPLACIAN 1 | |
Mat laplacian; | |
Mat laplacian_binary; | |
laplacian = myLaplacianFilter(data, 1); | |
imshow("my laplacian", laplacian); | |
#endif | |
#if __CHECK_OPENCV 1 | |
Mat cvlap; | |
Laplacian(data, cvlap, CV_32F, 3); | |
convertScaleAbs(cvlap, cvlap, 1, 0); | |
imshow("opencv laplacian", cvlap); | |
Mat canny; | |
Canny(data, canny, 50, 200); | |
imshow("opencv canny", canny); | |
#endif | |
waitKey(); | |
return 0; | |
} |
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 "myfilter.h" | |
#define PI 3.1415926535f | |
using namespace cv; | |
using namespace std; | |
//#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; | |
} | |
Mat mySobelFilter(Mat data, int direction, int color) | |
{ | |
Mat karnel; | |
karnel = Mat::zeros(Size(3, 3), CV_32F); | |
if (direction == 0) { | |
karnel.at<float>(0, 0) = 1; | |
karnel.at<float>(0, 2) = -1; | |
karnel.at<float>(1, 0) = 2; | |
karnel.at<float>(1, 2) = -2; | |
karnel.at<float>(2, 0) = 1; | |
karnel.at<float>(2, 2) = -1; | |
} | |
else { | |
karnel.at<float>(0, 0) = 1; | |
karnel.at<float>(0, 1) = 2; | |
karnel.at<float>(0, 2) = 1; | |
karnel.at<float>(2, 0) = -1; | |
karnel.at<float>(2, 1) = -2; | |
karnel.at<float>(2, 2) = -1; | |
} | |
#if _DEBUG 1 | |
cout << karnel << endl; | |
#endif | |
int height = data.size().height; | |
int width = data.size().width; | |
Mat out; | |
if (color == 0) { | |
out = data.clone(); | |
float sumR = 0; | |
float sumG = 0; | |
float sumB = 0; | |
for (int x = 1; x < width - 1; x++) { | |
for (int y = 1; y < height - 1; y++) { | |
for (int k = -1; k <= 1; k++) { | |
for (int l = -1; l <= 1; l++) { | |
sumB += (float)data.at<Vec3b>(y + l, x + k)[0] * karnel.at<float>(l + 1, k + 1); | |
sumG += (float)data.at<Vec3b>(y + l, x + k)[1] * karnel.at<float>(l + 1, k + 1); | |
sumR += (float)data.at<Vec3b>(y + l, x + k)[2] * karnel.at<float>(l + 1, k + 1); | |
} | |
} | |
if (sumB < 0.0f) sumB = 0; | |
if (sumG < 0.0f) sumG = 0; | |
if (sumR < 0.0f) sumR = 0; | |
out.at<Vec3b>(y - 1, x - 1)[0] = sumB; | |
out.at<Vec3b>(y - 1, x - 1)[1] = sumG; | |
out.at<Vec3b>(y - 1, x - 1)[2] = sumR; | |
sumB = 0.0f; | |
sumG = 0.0f; | |
sumR = 0.0f; | |
} | |
} | |
} | |
else { | |
Mat gray_data; | |
cvtColor(data, gray_data, CV_BGR2GRAY); | |
out = gray_data.clone(); | |
float sum_data = 0.0f; | |
for (int x = 1; x < width - 1; x++) { | |
for (int y = 1; y < height - 1; y++) { | |
for (int k = -1; k <= 1; k++) { | |
for (int l = -1; l <= 1; l++) { | |
sum_data += (float)gray_data.at<uchar>(y + l, x + k) * karnel.at<float>(l + 1, k + 1); | |
} | |
} | |
if (sum_data < 0.0f) sum_data = 0.0f; | |
out.at<uchar>(y - 1, x - 1) = (uchar)sum_data; | |
sum_data = 0.0f; | |
} | |
} | |
} | |
return out; | |
} | |
Mat myLaplacianFilter(Mat data, int color) | |
{ | |
Mat karnel; | |
karnel = Mat::zeros(Size(3, 3), CV_32F); | |
for (int i = 0; i < 3; i++) { | |
for (int j = 0; j < 3; j++) { | |
karnel.at<float>(i, j) = 1; | |
} | |
} | |
karnel.at<float>(1,1) = -8; | |
#if _DEBUG 1 | |
cout << karnel << endl; | |
#endif | |
int height = data.size().height; | |
int width = data.size().width; | |
Mat out; | |
if (color == 0) { | |
out = data.clone(); | |
float sumR = 0; | |
float sumG = 0; | |
float sumB = 0; | |
for (int x = 1; x < width - 1; x++) { | |
for (int y = 1; y < height - 1; y++) { | |
for (int k = -1; k <= 1; k++) { | |
for (int l = -1; l <= 1; l++) { | |
sumB += (float)data.at<Vec3b>(y + l, x + k)[0] * karnel.at<float>(l + 1, k + 1); | |
sumG += (float)data.at<Vec3b>(y + l, x + k)[1] * karnel.at<float>(l + 1, k + 1); | |
sumR += (float)data.at<Vec3b>(y + l, x + k)[2] * karnel.at<float>(l + 1, k + 1); | |
} | |
} | |
if (sumB < 0.0f) sumB = 0; | |
if (sumG < 0.0f) sumG = 0; | |
if (sumR < 0.0f) sumR = 0; | |
out.at<Vec3b>(y - 1, x - 1)[0] = sumB; | |
out.at<Vec3b>(y - 1, x - 1)[1] = sumG; | |
out.at<Vec3b>(y - 1, x - 1)[2] = sumR; | |
sumB = 0.0f; | |
sumG = 0.0f; | |
sumR = 0.0f; | |
} | |
} | |
} | |
else { | |
Mat gray_data; | |
cvtColor(data, gray_data, CV_BGR2GRAY); | |
out = gray_data.clone(); | |
float sum_data = 0.0f; | |
for (int x = 1; x < width - 1; x++) { | |
for (int y = 1; y < height - 1; y++) { | |
for (int k = -1; k <= 1; k++) { | |
for (int l = -1; l <= 1; l++) { | |
sum_data += (float)gray_data.at<uchar>(y + l, x + k) * karnel.at<float>(l + 1, k + 1); | |
} | |
} | |
if (sum_data < 0.0f) sum_data = 0.0f; | |
out.at<uchar>(y - 1, x - 1) = (uchar)sum_data; | |
sum_data = 0.0f; | |
} | |
} | |
} | |
return out; | |
} | |
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
#pragma once | |
#include <opencv2/opencv.hpp> | |
#include <iostream> | |
#include <cmath> | |
#define _DEBUG | |
cv::Mat myAverageFilter(cv::Mat data, cv::Size ksize); | |
cv::Mat myGaussianFilter(cv::Mat data, cv::Size ksize, float sigma); | |
cv::Mat mySobelFilter(cv::Mat data, int direction, int color); | |
cv::Mat myLaplacianFilter(cv::Mat data, int color); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment