23.11.13 (월) 38일차
이미지 블러로 처리하기
// ISP_filter_1.cpp
#pragma once
#include "ISP.h"
int main()
{
int datas[] = { 6, 4, 8, 9, 4, 4, 8, 64, 4, 6, 4, 8, 6, 4, 11, 1, 3, 1134, 5, 64, 5, 64 };
// 노이즈가 없는 대표 신호값을 정하시오.
const int length = sizeof(datas) / sizeof(datas[0]);
sort(datas, datas + length);
vector<int> vDatas(datas, datas + length);
sort(vDatas.begin(), vDatas.end());
int major = datas[length / 2];
int major_v = vDatas[length / 2];
cout << "중간값 : " << datas[length / 2] << endl;
std::string fileName = "../thirdparty/opencv_480/samples/data/lena.jpg";
cv::Mat src_gray = cv::imread(fileName, cv::ImreadModes::IMREAD_GRAYSCALE);
Mat src_gray_blur = src_gray.clone();
src_gray_blur = 0;
// filter 3x3 ... 1/9
const int filter_sz = 3;
float blur[] = {
1.0 / 9, 1.0 / 9, 1.0 / 9,
1.0 / 9, 1.0 / 9, 1.0 / 9,
1.0 / 9, 1.0 / 9, 1.0 / 9,
};
int half_kernelSize = filter_sz / 2;
for (size_t row = half_kernelSize; row < src_gray.rows - half_kernelSize; row++)
{
for (size_t col = half_kernelSize; col < src_gray.cols - half_kernelSize; col++)
{
int sum = 0;
for (int f_row = -half_kernelSize; f_row <= half_kernelSize; f_row++)
{
for (int f_col = -half_kernelSize; f_col <= half_kernelSize; f_col++)
{
int index = (row + f_row) * src_gray.cols + (col + f_col);
int f_index = (f_row + half_kernelSize) * filter_sz + (f_col + half_kernelSize);
sum += src_gray.data[index] * blur[f_index];
}
}
int index = (row)*src_gray.cols + (col);
src_gray_blur.data[index] = static_cast<uchar>(sum);
}
}
return 1;
}
이미지 끝 쪽이 잘린 것을 주변 픽셀 값으로 채우기
#pragma once
#include "ISP.h"
int main()
{
.. 중략 ..
// copy col + 1 to col, col[1] -> col[0]
// copy col to col + 1, col[98] -> col[99]
// copy row + 1 to row, row[1] -> row[0]
// copy row to row + 1, row[98] -> row[99]
// corner[4] ... 좌상 : (col[1] + row[1]) / 2
for (size_t row = 0; row < src_gray_blur.rows; row++)
{
int index_0 = row * src_gray_blur.cols + 0;
int index_1 = row * src_gray_blur.cols + 1;
int index_col = row * src_gray_blur.cols + (src_gray_blur.cols - 2);
int index_cols = row * src_gray_blur.cols + (src_gray_blur.cols - 1);
src_gray_blur.data[index_0] = src_gray_blur.data[index_1];
src_gray_blur.data[index_cols] = src_gray_blur.data[index_col];
}
for (size_t col = 0; col < src_gray_blur.cols; col++)
{
int idx_0 = col;
int idx_1 = src_gray_blur.rows + col + 1;
int index_row = (src_gray_blur.cols - 2) * src_gray_blur.rows + col;
int index_rows = (src_gray_blur.cols - 1) * src_gray_blur.rows + col;
src_gray_blur.data[idx_0] = src_gray_blur.data[idx_1];
src_gray_blur.data[index_rows] = src_gray_blur.data[index_row];
}
return 1;
}
주로 영상 확대 / 축소에 사용
// ISP_Filter_Sobel.cpp
#pragma once
#include "ISP.h"
int main()
{
std::string fileName = "../thirdparty/opencv_480/sources/samples/data/lena.jpg";
cv::Mat src_gray = cv::imread(fileName, cv::ImreadModes::IMREAD_GRAYSCALE);
Mat soble_x = Mat::zeros(src_gray.size(), CV_8UC1);
Mat soble_y = Mat::zeros(src_gray.size(), CV_8UC1);
Mat sobel_edge = Mat::zeros(src_gray.size(), CV_8UC1);
//filter 3x3 ... 1/9
const int filter_sz = 3;
//float blur[] = {
// 1.0 / 9, 1.0 / 9, 1.0 / 9,
// 1.0 / 9, 1.0 / 9, 1.0 / 9,
// 1.0 / 9, 1.0 / 9, 1.0 / 9,
//};
int sobel_x[] = {
-1, -2, -1,
0, 0, 0,
1, 2, 1,
};
int sobel_y[] = {
1, 0, -1,
2, 0, -2,
1, 0, -1,
};
int threshold = 80;
int half_kernelSize = filter_sz / 2;
for (size_t row = half_kernelSize; row < src_gray.rows - half_kernelSize; row++)
{
for (size_t col = half_kernelSize; col < src_gray.cols - half_kernelSize; col++)
{
int grad_x = 0;
int grad_y = 0;
for (int f_row = -half_kernelSize; f_row <= half_kernelSize; f_row++)
{
for (int f_col = -half_kernelSize; f_col <= half_kernelSize; f_col++)
{
int index = (row + f_row) * src_gray.cols + (col + f_col);
int f_index = (f_row + half_kernelSize) * filter_sz + (f_col + half_kernelSize);
grad_x += src_gray.data[index] * sobel_x[f_index];
grad_y += src_gray.data[index] * sobel_y[f_index];
}
}
int index = (row)*src_gray.cols + (col);
soble_x.data[index] = std::abs(grad_x);
soble_y.data[index] = std::abs(grad_y);
sobel_edge.data[index] = (unsigned char)sqrt((double)(grad_x * grad_x + grad_y * grad_y));//td::abs(grad_x) + std::abs(grad_y);
if (sobel_edge.data[index] >= threshold)
sobel_edge.data[index] = 255;
else
sobel_edge.data[index] = 0;
}
}
//copy col+1 to col, col[1]->col[0], left
for (size_t row = 0; row < sobel_edge.rows; row++)
{
int index_0 = row * sobel_edge.cols + 0;
int index_1 = row * sobel_edge.cols + 1;
sobel_edge.data[index_0] = sobel_edge.data[index_1];
index_0 = row * sobel_edge.cols + (sobel_edge.cols - 1);
index_1 = row * sobel_edge.cols + (sobel_edge.cols - 2);
sobel_edge.data[index_0] = sobel_edge.data[index_1];
}
//copy col to col+1, col[98]->col[99], right
for (size_t col = 0; col < sobel_edge.cols; col++)
{
int index_0 = (0) * sobel_edge.cols + col;
int index_1 = (1) * sobel_edge.cols + col;
sobel_edge.data[index_0] = sobel_edge.data[index_1];
index_0 = (sobel_edge.rows - 1) * sobel_edge.cols + col;
index_1 = (sobel_edge.rows - 2) * sobel_edge.cols + col;
sobel_edge.data[index_0] = sobel_edge.data[index_1];
}
//copy row+1 to row, row[1]->row[0], top
//copy row to row+1, row[98]->row[99], bottom
//corner[4]... 좌상, (col[1]+row[1])/2
// Sobel Filter
{
Mat mag;// = Mat::zeros(src_gray.size(), CV_16S);
Mat dx, dy;
Sobel(src_gray, dx, CV_32FC1, 1, 0);
Sobel(src_gray, dy, CV_32FC1, 0, 1);
magnitude(dx, dy, mag);
mag.convertTo(mag, CV_8UC1);
Mat edge = mag >= threshold;
int a = 0;
}
return 1;
}