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


- 조명이 좀 더 밝아지거나 어두워졌을때는 RGB보단 HSV가 조명 밝기의 영향을 덜 받는 좀 더 stable하다.
- 범위 선택 함수
void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst);
- src: 입력행렬
- lowerb: 하한 값(Mat 또는 Scalar)
- upperb: 상한 값(Mat 또는 Scalar)
- dst: 입력 영상과 동일 크기. CV_8UC1. 범위 안에 들어가는 픽셀 값만 255로 설정됨.

- 색상 범위 지정 기능을 이용한 컬러 필터 만들기
- 입력 컬러 영상에서 특정 색상 영역은 그대로 유지하고, 나머지 영역은 그레이스케일 형식으로 변환하는 효과 구현하기

- 영상에서 특정 색상을 제외한 나머지 부분만 그레이스케일로 변환
- inRange() 함수로 마스크 영상 생성
- 마스크 영상을 지정하여 copyTo()함수 수행
#include <iostream>
#include <algorithm>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
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);
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();
}
- 실행 결과

히스토그램 역투영
히스토그램 역투영
- 히스토그램 역투영(histogram backprojection)
- 주어진 히스토그램 모델에 영상의 픽셀들이 얼마나 일치하는지를 검사하는 방법
- 임의의 색상 영역을 검출할 때 효과적
- 조명의 밝기 변화의 영향을 줄이기 위해 보통 HSV 색 공간에서 HS성분만 사용하거나, YCrCb 색 공간에서 CrCb 성분만 사용
- 마우스로 선택한 영역과 유사한 색상 영역을 검출하는 예제

- 예제 프로그램
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("cropland.png", IMREAD_COLOR);
Rect rc = selectROI(src);
Mat src_ycrcb;
cvtColor(src, src_ycrcb, COLOR_BGR2YCrCb);
Mat crop = src_ycrcb(rc);
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(&crop, 1, channels, Mat(), hist, 2, histSize, ranges);
Mat backproj;
calcBackProject(&src_ycrcb, 1, channels, hist, backproj, ranges);
Mat dst = Mat::zeros(src.rows, src.cols, CV_8UC3);
src.copyTo(dst, backproj);
imshow("dst", dst);
waitKey();
}
- 실행 결과

- 히스토그램 역투영 함수
void calcBackProject(const Mat* images, int nimages, const int* channels, InputArray hist, OutputArray backProject, const float** ranges,
double scale = 1, bool uniform = true);
- images: 입력 영상 주소 (또는 입력 영상 배열 주소)
- nimages: 입력 영상 개수
- channels: 입력 히스토그램
- backProject: (출력) 히스토그램 역투영 결과 행렬. 입력 영상과 동일 크기, CV_8U. 발생 빈도가 높으면 원소 값이 크게 나타남.
- ranges: 히스토그램 빈 경계값 배열의 배열
- 히스토그램 역투영을 이용한 살색 검출
1) 기준 영상으로부터 살색에 대한 컬러 히스토그램을 미리 계산

2) 입력 영상에서 미리 구한 살색 히스토그램에 부합하는 픽셀을 선별

- 히스토그램 역투영을 이용한 살색 검출 예제
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main()
{
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);
...
- 실행 결과
(가우시안 블러 처리 전)

(가우시안 블러 처리 후)
