OpenCV Image Filtering(1)

JuHwan Kim·2022년 4월 7일
0

OpenCV

목록 보기
1/1

영상 출력 방법

컬러 영상 출력

cppIMREAD_COLOR

그레이 스케일 영상 출력은 GRAYSCALE이나 cvtColor를 사용

cppIMREAD_GRAYSCALE

cppcv::cvtColor(img, img, COLOR_BGR2GRAY);

Mat imread(const String& filename, int flags = IMREAD_COLOR);

filename : 불러올 영상 파일 이름
flags : 영상 파일 불러오기 옵션 플래그, ImreadModes 열거형 상수를 지정
반환 값 : 불러온 영상 데이터(Mat 객체)

이미지를 불러오고, 이미지가 없다면 에러가 발생하도록 하는 코드

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv
using namespace std

int main(void)
{
	cout << "Hello OpenCV!" << CV_VERSION << endl;
    
    Mat img;
    img = imread("img_name");
    
    if (img.empty())
    {
    	cerr << "Image load failed!" << endl;
        return -1;
    }
    
    nameWindow("image");
    imshow("image", img);
    
    waitKey();
    destroyAllWindows();
    return 0;
}

영상의 밝기 조절

영상의 밝기 조절(단순 연산)

void brightness1()
{
	Mat src = imread("img_name", IMREAD_GRAYSCALE);
    
    if(src.empty())
    {
    	cerr << "Image load failed!" << endl;
        return;
    }
    
    Mat dst = src + 100; // 픽셀 값을 늘려서 밝게 만듬
    
    imshow("src", src);
    imshow("dst", dst);
    waitKey();
    destroyAllWindows();
}

영상의 밝기 조절(픽셀 접근)
Mat 행렬의 원소 값 참조 방법을 사용하면 밝기 조절을 직접 구현할 수 있음
입력 영상의 모든 픽셀을 방문하면서 픽셀 값에 일정한 상수를 더하거나 빼면,밝기 조절이 적용됨
Mat::at()로 dst 영상의 픽셀 값을 참조하기 때문에 src와 크기 및 타입이 같은 dst 객체 생성이 필요함

void brightness2()
{
	Mat src = imread("img_name", IMREAD_GRAYSCALE);
    
    if(src.empty())
    {
    	cerr << "Image load failed!" << endl;
        return;
    }
    
    Mat dst(src.rows, src.cols, src.type());
    
    for (int j = 0; j < src.rows; j++)
    {
    	for (int i = 0; i < src.cols; i++)
        {
        	dst.at<uchar>(j, i) = src.at<uchar>(j, i) + 100;
        }
    }
    
    imshow("src", src);
    imshow("dst", dst);
    waitKey();
    destroyAllWindows();
}

픽셀로 접근했을 때, 밝은 픽셀 주변에서 급격하게 어두운 픽셀이 나타난다.
그 이유는 포화 연산을 수행하지 않았기 때문

포화 연산 : 행렬의 원소 값을 설정할 때, 원소 자료형이 가질 수 있는 값의 범위를 벗어나는 경우, 해당 자료형의 최솟값 또는 최댓값으로 원소 값을 설정하는 연산을 OpenCV에서 포화(Saturation) 연산이라고 부름

포화연산 예시1

for (int j = 0; j < src.rows; j++)
{
    for (int i = 0; i < src.cols; i++)
    {
        int v = src.at<uchar>(j, i) + 100;
        dst.at<uchar>(j, i) = v > 255 ? 255 : v < 0 ? 0 : v;
    }
}

포화연산 예시2

int v = src.at<uchar>(j, i) + 100;
dst.at<uchar>(j, i) = saturate_cast<uchar>(v);

영상 명암비 조절

기본적인 명암비 조절
단순 곱셈 / 나눗셈 연산을 이용
OpenCV는 C / C++ 실수형 자료형과 Mat 객체 사이의 곱셈 연산자 재정의도 제공
그 결과 Mat 행렬의 모든 원소에 주어진 실수 값을 곱한 결과 행렬을 반환함
이때 결과 행렬에 대해 포화 연산도 함께 수행

코드를 적용하고 보면, 전체적으로 픽셀 값이 포화되어 흰색으로 나타나는 영역이 너무 많고, 이로 인해 사물 윤곽 구분이 더 어려워짐
그러므로 픽셀 값에 일정 상수를 단순히 곱하여 명암비를 조절하는 방식은 실전에서는 잘 사용하지 않음

void contrast1()
{
	Mat src = imread("img_name", IMREAD_GRAYSCALE);
    
    if(src.empty())
    {
    	cerr << "Image load failed!" << endl;
        return;
    }
    
    float s = 2.f;
    Mat dst = s * src;
    
    imshow("src", src);
    imshow("dst", dst);
    waitKey();
    destroyAllWindows();
}

효과적인 명암비 조절
기본적인 명암비 보다 좀 더 자연스럽게 명암비가 증가됨
alpha 값이 양수면 선명해 지고, 음수면 흐려지는 것을 알 수 있음

void contrast2()
{
	Mat src = imread("img_name", IMREAD_GRAYSCALE);
    
    if(src.empty())
    {
    	cerr << "Image load failed!" << endl;
        return;
    }
    
    float alpha = 1.f; //alpha 값이 1.0
    Mat dst = src + (src - 128) * alpha;
    
    imshow("src", src);
    imshow("dst", dst);
    waitKey();
    destroyAllWindows();
}
profile
소소한 개발자

0개의 댓글