[Intel AI SW 아카데미] 영상처리 - 필터링

Jimeaning·2023년 11월 13일
0

Intel AIoT

목록 보기
15/38

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;
}
profile
I mean

0개의 댓글