[Computer Vision] 영상처리 기본 연산

개념

Mat

  1. OpenCV에서 사용하는 이미지 단위. 왼쪽 위에서 시작하여 왼쪽에서 오른쪽으로, 위에서 아래 방향으로 픽셀 값을 저장한다.
  2. Mat 객체에 접근하여 이미지를 픽셀 단위나 채널 단위로 값을 확인하거나 바꿀 수 있다.
  3. 칼라의 경우 B, G, R 순서로 값이 저장되어 있다.
  4. 값은 unsigned char(uchar)로 저장됨. (범위 : 0 ~ 255)
  5. at을 통해 배열 요소에 접근한다. 
    1. Gray Scale : image.at<uchar>(y, x);
    2. Color : image.at<cv::Vec3b>(y, x)[channel]; // 배열의 인덱스로 B, G, R 요소에 접근 가능
      1. image.at(y, x)[0]; // Blue
      2. image.at(y, x)[1]; // Green
      3. image.at(y, x)[2]; // Red
  6. cv::saturate_cast<uchar>(a);
    1.  a를 uchar의 범위(0 ~ 255)로 변환
      1. a = 280 이면 a = 255으로 변환
      2. a = -20 이면 a = 0으로 변환

※ 실습 시 알고 있어야 하는 사항들

  • 이미지 저장 방법.
    • cv::imwrite("저장할 이름.jpg", 이미지_변수_이름);
  • 픽셀 값이 0 ~ 255의 범위를 벗어날 경우 이미지가 깨져서 보이는 경우.
    • cv::saturate_cast <uchar>()로 값 보정을 할 것.
  • 이미지를 흑백으로 읽는 방법
    • cv::imread("ImageName", cv::IMREAD_GRAYSCALE);

 

실습1 : 이미지 반전

bmp 파일을 일고 이미지를 반전시키고, 반전된 이미지를 파일로 저장하세요.

ex) 255 -> 0, 0 -> 255

 

실습1 정답

#include "opencv2/opencv.hpp"
#include <iostream>

int main(void)
{
	cv::Mat result_img, img;
	img = cv::imread("cat.bmp");
	img.copyTo(result_img);

	if (img.empty())
	{
		std::cerr << "Image load failed!" << std::endl;
		return -1;
	}

	for (int y = 0; y < img.rows; y++)
	{
		for (int x = 0; x < img.cols; x++)
		{
			int b = 255 - (unsigned int)img.at<cv::Vec3b>(y, x)[0];
			int g = 255 - (unsigned int)img.at<cv::Vec3b>(y, x)[1];
			int r = 255 - (unsigned int)img.at<cv::Vec3b>(y, x)[2];
			result_img.at<cv::Vec3b>(y, x)[0] = cv::saturate_cast<uchar>(b);
			result_img.at<cv::Vec3b>(y, x)[1] = cv::saturate_cast<uchar>(g);
			result_img.at<cv::Vec3b>(y, x)[2] = cv::saturate_cast<uchar>(r);
		}
	}

	cv::imshow("Original Image", img);
	cv::imshow("Result Image", result_img);
	cv::imwrite("cat_inverted.jpg", result_img);
	cv::waitKey();
	return 0;
}

 

실습 1 모범답안

실습1 정답과 같다.

 

실습2 : 이진화 구현

bmp 파일을 흑백으로 읽고, 이미지를 이진화하여 파일로 저장하세요. 여기서 이진화란 0부터 255까지로 분포된 값들을 0255 두 가지 값만 가지도록 하는 연산으로 정의합니다. (보통은 01로 변환하는 작업을 의미하나 편의상 0255로 하도록 하겠습니다.)

이진화 연산 수식

 

실습2 정답

#include "opencv2/opencv.hpp"
#include <iostream>

int main(void)
{
	cv::Mat result_img, img;
	img = cv::imread("cat.bmp", cv::IMREAD_GRAYSCALE);
	img.copyTo(result_img);

	if (img.empty())
	{
		std::cerr << "Image load failed!" << std::endl;
		return -1;
	}

	for (int y = 0; y < img.rows; y++)
	{
		for (int x = 0; x < img.cols; x++)
		{
			unsigned int tmp = (unsigned int)img.at<uchar>(y, x) < 128 ? 0 : 255;
			result_img.at<uchar>(y, x) = cv::saturate_cast<uchar>(tmp);
		}
	}

	cv::imshow("Original Image", img);
	cv::imshow("Result Image", result_img);
	cv::imwrite("cat_binarized.jpg", result_img);
	cv::waitKey();
	return 0;
}

 

실습2 모범답안

내 정답과 비슷하다.

'공부 > CV' 카테고리의 다른 글

[Computer Vision] Filtering  (0) 2024.10.09