printf("ho_tari\n");

Chapter5 : 영상의 밝기와 명암비 조절 본문

OpenCV

Chapter5 : 영상의 밝기와 명암비 조절

호타리 2023. 9. 14. 13:52

<OpenCV_Projects.cpp>

#include <opencv2/opencv.hpp>

extern void example();
extern void brightness();
extern void brightness4();
extern void contrast();
extern void show_hist();
extern void histogram_streching();

int main() 
{
    std::cout << CV_VERSION << std::endl;

    //example();
    //brightness();
    //brightness4();
    //contrast();
    //show_hist();
    histogram_streching();
}

 

<example.cpp>

#pragma once
#include <opencv2/opencv.hpp>

//이미지를 BGR -> GRAYSCALE 또는 GRAYSCALE을 BGR로 바꾸는 함수
void example() 
{
	cv::Mat img1 = cv::imread("lenna.bmp");
	cv::Mat img2;
	cvtColor(img1, img2, cv::COLOR_BGR2GRAY); // BGR->GRAYSCALE로 바꾸는 함수
	cv::imshow("IMG1", img1);
	cv::imshow("IMG2", img2);
	cv::waitKey();
	cv::destroyAllWindows();
}

<compile 결과>

 

<brightness.cpp>

#pragma once
#include <opencv2/opencv.hpp>

//영상의 밝기 조절 함수
void brightness() 
{
	cv::Mat src = cv::imread("lenna.bmp", cv::IMREAD_GRAYSCALE);
	if (src.empty()) return;
	cv::Mat dst(src.rows, src.cols, src.type());

	for (int i = 0; i < src.rows; ++i) {
		for (int j = 0; j < src.cols; ++j) {
			dst.at<uchar>(i, j) = cv::saturate_cast<uchar>(src.at<uchar>(i, j) + 100);
			//255를 넘어가는 값을 자동으로 255로 설정해주는 함수
			/*
			int temp = src.at<uchar>(i,j_) + 100;
			dst.at<uchar>(i,j) = temp > 255 ? 255: temp<0 ? 0 : temp;
			*/
		}
	}

	cv::imshow("SRC", src);
	cv::imshow("DST", dst);
	cv::waitKey();
	cv::destroyAllWindows();
}

<compile 결과>

<brightness4.cpp>

#pragma once
#include <opencv2/opencv.hpp>

void on_brightness(int pos, void* userdata);

//트랙바를 활용한 영상의 밝기 조절 함수
void brightness4() 
{
	cv::Mat src = cv::imread("lenna.bmp", cv::IMREAD_GRAYSCALE);
	if (src.empty()) {
		std::cerr << "Image load failed!" << std::endl;
		return;
	}
	cv::namedWindow("dst");
	cv::createTrackbar("Brightness", "dst", 0, 100, on_brightness, (void*)&src);
	on_brightness(0, (void*)&src);
	cv::waitKey();
	cv::destroyAllWindows();
}
void on_brightness(int pos, void* userdata) {
	cv::Mat src = *(cv::Mat*)userdata;
	cv::Mat dst = src + pos;
	cv::imshow("dst", dst);
}

<compile 결과>

트랙바를 오른쪽으로 드래그하면 밝기가 밝아진다

 

<contrast.cpp>

#pragma once
#include <opencv2/opencv.hpp>

//영상의 명암조절(또렷하게 하기) 함수
void contrast() 
{
	cv::Mat src = cv::imread("lenna.bmp", cv::IMREAD_GRAYSCALE);
	float alpha = 1.0f;
	cv:: Mat dst = (1 + alpha) * src - 128 * alpha;
	cv::imshow("SRC", src);
	cv::imshow("DST", dst);
	cv::waitKey();
	cv::destroyAllWindows();
}

<compile 결과>

 

<show_hist.cpp>

#pragma once
#include <opencv2/opencv.hpp>

static cv::Mat calcGrayHist(const cv::Mat&);
static cv::Mat getGrayHistImage(const cv::Mat&);

//이미지의 픽셀값을 히스토그램으로 출력하는 함수
void show_hist() 
{
	cv::Mat src = cv::imread("hawkes.bmp", cv::IMREAD_GRAYSCALE);
	if (src.empty()) return;
	cv::Mat hist1 = calcGrayHist(src);
	cv::Mat hist_img = getGrayHistImage(hist1);
	cv::imshow("HISTOGRAM", hist_img);
	cv::imshow("SRC", src);
	cv::waitKey();
	cv::destroyAllWindows();
}
cv::Mat calcGrayHist(const cv::Mat& img) 
{
	cv::Mat hist;
	int channels[] = { 0 };
	int dims = 1;
	int histsize[] = { 256 };
	float graylevel[] = { 0,256 };
	const float* ranges[] = { graylevel };
	calcHist(&img, 1, channels, cv::noArray(), hist, dims, histsize, ranges);
	//가로가 256픽셀, 세로가 최대 100픽셀인 그래프 생성
	return hist;
}
cv::Mat getGrayHistImage(const cv::Mat& hist) 
{
	double histMax;
	minMaxLoc(hist, 0, &histMax);
	cv::Mat imgHist(100, 256, CV_8UC1, cv::Scalar(255)); // 100 * 256크기의 히스토그램을 생성
	for (int i = 0; i < 256; ++i) 
	{
		line(imgHist, cv::Point(i, 100), cv::Point(i, 100 - cvRound(hist.at<float>(i, 0) * 100 / histMax)), cv::Scalar(0));
	}
	return imgHist;
}

<compile 결과>

 

<histogram_stretching.cpp>

#pragma once
#include <opencv2/opencv.hpp>

static cv::Mat calcGrayHist(const cv::Mat&);
static cv::Mat getGrayHistImage(const cv::Mat&);

cv::Mat calcGrayHist(const cv::Mat& img) 
{
	cv::Mat hist;
	int channels[] = { 0 };
	int dims = 1;
	int histsize[] = { 256 };
	float graylevel[] = { 0,256 };
	const float* ranges[] = { graylevel };
	calcHist(&img, 1, channels, cv::noArray(), hist, dims, histsize, ranges);
	//가로가 256픽셀, 세로가 최대 100픽셀인 그래프 생성
	return hist;
}
cv::Mat getGrayHistImage(const cv::Mat& hist) 
{
	double histMax;
	minMaxLoc(hist, 0, &histMax);
	cv::Mat imgHist(100, 256, CV_8UC1, cv::Scalar(255)); // 100 * 256크기의 히스토그램을 생성
	for (int i = 0; i < 256; ++i) 
	{
		line(imgHist, cv::Point(i, 100), cv::Point(i, 100 - cvRound(hist.at<float>(i, 0) * 100 / histMax)), cv::Scalar(0));
	}
	return imgHist;
}

//이미지의 히스토그램을 보고 명암비를 조절하는 함수
void histogram_streching() {
	cv::Mat src = cv::imread("hawkes.bmp", cv::IMREAD_GRAYSCALE);
	if (src.empty()) return;
	double min = 0.0;
	double max = 0.0;
	minMaxLoc(src, &min, &max);
	cv::Mat dst = ((src - min) / (max - min)) * 255;
	cv::Mat hist1 = calcGrayHist(src);
	cv::Mat hist_img = getGrayHistImage(hist1);
	cv::imshow("SRC", src);
	cv::imshow("SRC_HISTOGRAM", hist_img);
	cv::imshow("DST", dst);
	cv::imshow("DST_HISTOGRAM", getGrayHistImage(calcGrayHist(dst)));
	cv::waitKey();
	cv::destroyAllWindows();
}

<compile 결과>