4. 영상의 밝기와 명암비 조절

OpenJR·2022년 4월 11일
0
post-custom-banner

영상의 밝기 조절

평균 밝기 보정

int main()
{
	Mat src = imread ("lenna.bmp", IMREAD_GRAYSCALE);
	int m = mean(src)[0];							//이렇게 사용
	Mat dst = src + (128 - m);
}

명암비 조절

간단한 명암비 조절

dst(x,y)=s×src(x,y)dst(x,y) = s\times src(x,y)
Mat src = imread ("lenna.bmp", IMREAD_GRAYSCALE);
Mat dst = 3 * src;

효과적인 명암비 조절

dst(x,y)=src(x,y)+(src(x,y)128)×alphadst(x,y) = src(x,y)+(src(x,y)-128)\times alpha
Mat src = imread ("lenna.bmp", IMREAD_GRAYSCALE);
float alpha = 1.0f;
Mat dst = src + (src - 128) * alpha;

평균밝기를 고려한 명암비 조절

ds(x,y)=src(x,y)+(src(x,y)m)×αds(x,y)=src(x,y)+(src(x,y)-m)\times\alpha
Mat src = imread("lenna.bmp", IMREAD_GRAYSCALE);
int m = int(mean(src)[0]);

float alpha = 1.0f;
Mat dst = src + (src - m) * alpha;

히스토그램

히스토그램 함수

void calcHist(const Mat* images, int nimages, const int* channels,
              InputArray mask, OutputArray hist, int dims, const int* histSize,
              const float** ranges, bool uniform = true, bool accumulate = false );

// 1차원
Mat hist;
int nimages = 1;
int channels[] = { 0 };
int dims = 1;
const int histSize[] = {256};
float range[] = {0, 256}
const float* ranges[] = {range};

calcHist(&src, nimages, channels, noArray(), hist, dims, histSize, ranges);

// 2차원
Mat hist;
int nimages = 1;
int channels[] = { 1, 2 }; \\ YCrCb [0, 1, 2]
int dims = 2;
int histSize[] = { 256, 256 };
float cr_range[] = { 0, 256 };
float cb_range[] = { 0, 256 };
const float* ranges[] = { cr_range, cb_range };

calcHist(&src, nimages, channels, mask, hist, dims, histSize, ranges);

images: 입력 영상의 배열 또는 입력 영상의 주소. 영상의 배열인 경우, 모두 크기와 깊이가 같아야 함.

nimages: 영상 영상의 개수

channels: 히스토그램을 구할 채널을 나타내는 정수형 배열

mask: 마스크 영상. 입력 영상 전체에서 히스토그램을 구하려면 Mat() 또는 noArray() 지정.

hist: (출력) 히스토그램. dims-차원 배열. Mat 또는 SparseMat.

dims: 출력 히스토그램 차원

histSize: 히스토그램 각 차원의 크기를 나타내는 배열

ranges: 히스토그램 각 차원의 최솟값과 최댓값을 원소로 갖는 배열의 배열 (uniform = true인 경우)

uniform: 히스토그램 빈의 간격이 균등한지를 나타내는 플래그

accumulate: 누적 플래그. 이 값이 true이면 hist 배열을 초기화하지 않고 누적하여 히스토그램을 계산함

히스토그램 탬플릿 함수

Mat calcGrayHist(const Mat& img)
{
	CV_Assert(img.type() == CV_8U);

	Mat hist;
	int channels[] = { 0 };
	int dims = 1;
	const int histSize[] = { 256 };
	float graylevel[] = { 0, 256 };
	const float* ranges[] = { graylevel };

	calcHist(&img, 1, channels, noArray(), hist, dims, histSize, ranges);

	return hist;
}

Mat getGrayHistImage(const Mat& hist)
{
	CV_Assert(hist.type() == CV_32F);
	CV_Assert(hist.size() == Size(1, 256));

	double histMax = 0.;
	minMaxLoc(hist, 0, &histMax);

	Mat imgHist(100, 256, CV_8U, Scalar(255));
	for (int i = 0; i < 256; i++) {
		line(imgHist, Point(i, 100),
			Point(i, 100 - cvRound(hist.at<float>(i, 0) * 100 / histMax)), Scalar(0));
	}

	return imgHist;
}

Mat hist = calcGrayHist(src);
Mat imgHist = getGrayHistImage(hist);

히스토그램 스트레칭

dst(x,y)=src(x,y)GminGmaxGmin×255dst(x,y)=\frac{src(x,y)-G_{min}}{G_{max}-G_{min}}\times 255
double gmin, gmax;
minMaxLoc(src, &gmin, &gmax);
dst = (src - gmin) * 255 / (gmax - gmin);

히스토그램 평활화

void equalizeHist(InputArray src, OutputArray dst);

mat dst;
equalizeHist(src, dst);

src: 입력 영상. 8비트 1채널.

dst: 결과 영상. src와 같은 크기, 같은 타입.

profile
Jacob
post-custom-banner

0개의 댓글