컴퓨터 비전

OpenCV 컬러 영상 처리

Jagbbum 2023. 10. 24. 10:57

OpenCV - BGR 순서를 기본으로 사용

Mat img1 = imread("lenna.bmp", IMREAD_COLOR);
Mat img2(rows, cols, CV_8UC3);

Mat img3 = imread("lenna.bmp", IMREAD_GRAYSCALE);
Matimg4;
cvtColor(img3, img4, COLOR_GRAY2BGR);

 

컬러 영상 반전

Mat dst(src.rows, src.cols, CV_8UC3);

for (int y=0; y<src.rows; y++){
	for(int x=0; x<src.cols; x++){
    	Vec3b& p1 = src.at<Vec3b>(y,x);
        Vec3b& p2 = dst.at<Vec3b>(y,x);
    	
        p2[0] = 255 - p1[0];
    	p2[1] = 255 - p1[1];
        p2[2] = 255 - p1[2];
    }
}
------------------------------------------
Mat dst = Scalar(255, 255, 255)- src;

 

컬러 영상을 그레이스케일로 변환

Y = 0.299R + 0.587G + 0.114b

for (int y=0; y<src.rows; y++){
	for(int x=0; x<src.cols; x++){
    	Vec3b& p1 = src.at<Vec3b>(y,x);
        unchar b = p1[0];
        unchar g = p1[1];
        unchar r = p1[2];
        
        unchar gray = (unchar)(0.299*r + 0.584*g + 0.114*b + 0.5); // 0.5는 반올림
        
        dst.at<unchat>(y,x) = gray;
    }
}
-----------------------------------------------
 unchar gray = (unchar)(299*r + 584*g + 114*b) / 1000;
 ----------------------------------------------
 #define RGB2GRAY(r,g,b) ((4899*(r) + 9617*(g) + 1868*(b)) >> 14)
 ----------------------------------------------
 Mat dst;
 cvtColor(src, dst, COLOR_BGR2GRAY)

색공간

채널 분리

Mat src = imread("lenna.bmp");

vector<Mat> planes;
split(src, planes);

imshow("im1",planes[0]);
imshow("im2",planes[1]);
imshow("im3",planes[2]);

채널 결합

swap(planes[0], planes[2]);

Mat dst;
merge(planes, dst);

컬러 영상 히스토그램 평활화

- 밝기 성분에 대해서만 히스토그램 평활화 수행 (YCrCb 공간)

Mat src_ycrcb;
cvtColor(src, src_ycrcb, COLOR_BGR2YCrCb);

vector<Mat> planes;
split(src_ycrcb, planes);

equalizrHist(planes[0], planes[0]);

Mat dst_ycrcb;
merge(planes, dst);

Mat dst
cvtColor(dst_ycrcb, dst, COLOR_YCrCb2BGR);

 

컬러 영상 색감 바꾸기

vector<Mat> channels;
split(src, channels);

for (int y=0; y<src.rows; y++){
	for(int x=0; x<src.cols; x++){
    	channels[2].at<unchar>(y, x) = curve1[channels[2].at<unchar>(y, x)];
        channels[0].at<unchar>(y, x) = curve1[channels[2].at<unchar>(y, x)];
    }
}

Mat dst;
merge(channels, dst);

특정 색상 영역 추출하기

RGB, HSV, YCrCb등의 색 공간에서 각 색상 성분의 범위를 지정하여 특정 색상 영역 추출

 

범위 선택 함수

void inRange(InputArray src, InputArray lowerb,
                          InputArray upperb, OutputArray dst);

 

색상 범위 지정 기능을 이용한 컬러 필터

int pos_hue1 = 50, pos_hue2 = 80, pos_sat1 = 150, pos_sat2 = 255;
Mat src, src_hsv, dst, mask;

void on_hsv_changed(int, void*)
{
	Scalar lowerb(pos_hue1, pos_sat1, 0);
	Scalar upperb(pos_hue2, pos_sat2, 255);
	inRange(src_hsv, lowerb, upperb, mask);

	cvtColor(src, dst, COLOR_BGR2GRAY);
	cvtColor(dst, dst, COLOR_GRAY2BGR);
	src.copyTo(dst, mask);

	imshow("mask", mask);
	imshow("dst", dst);
}

int main()
{
	src = imread("candies.png", IMREAD_COLOR);

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

	cvtColor(src, src_hsv, COLOR_BGR2HSV);

	namedWindow("src");
	namedWindow("mask");
	namedWindow("dst");

	imshow("src", src);

	createTrackbar("Lower Hue", "dst", &pos_hue1, 179, on_hsv_changed);
	createTrackbar("Upper Hue", "dst", &pos_hue2, 179, on_hsv_changed);
	createTrackbar("Lower Sat", "dst", &pos_sat1, 255, on_hsv_changed);
	createTrackbar("Upper Sat", "dst", &pos_sat2, 255, on_hsv_changed);
	on_hsv_changed(0, 0);

	waitKey();
}

 

히스토그램 역투영

- 주어진 히스토그램 모델에 영상의 픽셀들이 얼마나 일치하는 지를 검사하는 방법

 

히스토그램 역투영 함수

void calcBackProject( const Mat* images, int nimages,
                                 const int* channels, const SparseMat& hist,
                                 OutputArray backProject, const float** ranges,
                                 double scale = 1, bool uniform = true );

 

살색 검출하는 코드

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

using namespace std;
using namespace cv;

int main()
{
	// Calculate CrCb histogram from a reference image

	Mat ref, ref_ycrcb, mask;
	ref = imread("ref.png", IMREAD_COLOR);
	mask = imread("mask.bmp", IMREAD_GRAYSCALE);
	cvtColor(ref, ref_ycrcb, COLOR_BGR2YCrCb);

	Mat hist;
	int channels[] = { 1, 2 };
	int cr_bins = 128; int cb_bins = 128;
	int histSize[] = { cr_bins, cb_bins };
	float cr_range[] = { 0, 256 };
	float cb_range[] = { 0, 256 };
	const float* ranges[] = { cr_range, cb_range };

	calcHist(&ref_ycrcb, 1, channels, mask, hist, 2, histSize, ranges);

#if 1
	Mat hist_norm;
	normalize(hist, hist_norm, 0, 255, NORM_MINMAX, CV_8UC1);
	resize(hist_norm, hist_norm, Size(256 * 3, 256 * 3));
	imshow("hist_norm", hist_norm);
#endif

	Mat src, src_ycrcb;
	src = imread("kids.png", IMREAD_COLOR);
	cvtColor(src, src_ycrcb, COLOR_BGR2YCrCb);

	Mat backproj;
	calcBackProject(&src_ycrcb, 1, channels, hist, backproj, ranges);

	GaussianBlur(backproj, backproj, Size(), 1.0);
	backproj = backproj > 50;

	Mat dst = Mat::zeros(src.rows, src.cols, CV_8UC3);
	src.copyTo(dst, backproj);

	imshow("ref", ref);
	imshow("mask", mask);
	imshow("src", src);
	imshow("backproj", backproj);
	imshow("dst", dst);
	waitKey();
}

'컴퓨터 비전' 카테고리의 다른 글

OpenCV 이진 영상 처리  (0) 2023.10.26
OpenCV 영상의 특징 추출  (0) 2023.10.25
OpenCV 특정점 검출과 매칭  (1) 2023.10.23
OpenCV 필터링  (0) 2023.10.20
OpenCV 영산의 산술  (0) 2023.10.19