개념
Mat
- OpenCV에서 사용하는 이미지 단위. 왼쪽 위에서 시작하여 왼쪽에서 오른쪽으로, 위에서 아래 방향으로 픽셀 값을 저장한다.
- Mat 객체에 접근하여 이미지를 픽셀 단위나 채널 단위로 값을 확인하거나 바꿀 수 있다.
- 칼라의 경우 B, G, R 순서로 값이 저장되어 있다.
- 값은 unsigned char(uchar)로 저장됨. (범위 : 0 ~ 255)
- at을 통해 배열 요소에 접근한다.
- Gray Scale : image.at<uchar>(y, x);
- Color : image.at<cv::Vec3b>(y, x)[channel]; // 배열의 인덱스로 B, G, R 요소에 접근 가능
- image.at(y, x)[0]; // Blue
- image.at(y, x)[1]; // Green
- image.at(y, x)[2]; // Red
- cv::saturate_cast<uchar>(a);
- a를 uchar의 범위(0 ~ 255)로 변환
- a = 280 이면 a = 255으로 변환
- a = -20 이면 a = 0으로 변환
- a를 uchar의 범위(0 ~ 255)로 변환
※ 실습 시 알고 있어야 하는 사항들
- 이미지 저장 방법.
- 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까지로 분포된 값들을 0과 255 두 가지 값만 가지도록 하는 연산으로 정의합니다. (보통은 0과 1로 변환하는 작업을 의미하나 편의상 0과 255로 하도록 하겠습니다.)
실습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 |
---|