728x90
728x90
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
#include <Windows.h>
#include <string.h>
using namespace cv;
using namespace std;
Mat histogram, histogramImage; // λ λ μμκ³Ό λ λ μμμ νμ€ν κ·Έλ¨
Mat histogram2, histogramImage2; // CPU μμκ³Ό CPU μμμ νμ€ν κ·Έλ¨
Mat histogramNew; // μννν λμ΄ μμ±λ 룩μ
-ν
μ΄λΈ
Mat image, image2; // λΆλ¬μ€λ μ΄λ―Έμ§ 1,2
Mat histogramSum, histogramSum2; // λ λ, CPU μμμ ννν ν κ²°κ³Όλ₯Ό λ΄λ ν
μ΄λΈ1, 2
Mat tmp, tmp2;
// params : image
// νμ€ν κ·Έλ¨μ νμΈν μμ
// params : histogram
// κ³μ°λμ΄ λ°νλ νμ€ν κ·Έλ¨
// params : bins
// νμ€ν κ·Έλ¨μ xμΆ μμ μ
// params : range_max
// νμ€ν κ·Έλ¨μ xμΆ μ΅λ μμ μ
// κ³Όμ : μννν κ³Όμ λ§ μΆκ°νλ©΄ λλ€.
// μ΄λ―Έμ§μ λν νμ€ν κ·Έλ¨ κ³μ°
void CalcHistogram(Mat image, Mat& histogram, int bins, int range_max = 256) {
// νμ€ν κ·Έλ¨ κ°μ μ μ₯ν Mat μΈμ€ν΄μ€ μμ±, 0μΌλ‘ μ΄κΈ°ν
histogram = Mat(bins, 1, CV_32F, Scalar(0));
// xμΆ κ° κ°κ²©
float gap = (float)range_max / bins;
// μμμ μννλ©΄μ νμλ₯Ό μ²λ¦¬
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++) {
// var : workPixel
// μ²λ¦¬ν νμ
// auto : μ»΄νμΌ μμ μμ μ»΄νμΌλ¬κ° λ¬Έλ§₯μ λ³΄κ³ μλμΌλ‘ λ³μ νμ
μ μ§μ , ν
νλ¦Ώκ°μ κ³³μ μ¬μ©μ νΈλ¦¬
auto workPixel = image.at<uchar>(i, j);
// ν΄λΉ νμκ° λ€μ΄κ° μμμ κ³μ°
int idx = (int)(workPixel / gap);
// νμ€ν κ·Έλ¨μ μμμ κ°μ λμ
histogram.at<float>(idx)++;
}
}
}
string OpenFileDialog()
{
char name[MAX_PATH] = { 0, };
OPENFILENAMEA ofn;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAMEA);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = "λͺ¨λ νμΌ(*.*)\0*.*\0";
ofn.lpstrFile = name;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.lpstrDefExt = "";
string strName;
if (GetOpenFileNameA(&ofn))
strName = name;
return strName;
}
// νμ€ν κ·Έλ¨
void GetHistogramImage(Mat histogram, Mat& histogramImage, Size size = Size(256, 200)) {
// 255λ‘ λΉ νμ€ν κ·Έλ¨ μμμ μμ±
histogramImage = Mat(size, CV_8U, Scalar(255));
// νμ€ν κ·Έλ¨ ν μμμ ννν λλΉ
float gap = (float)(histogramImage.cols / histogram.rows);
// νμ€ν κ·Έλ¨μ λΉλκ°μ μ΅μκ° 0, μ΅λκ° μΆλ ₯ μμμ λμ΄κ°μ κ°λλ‘ μ‘°μ
normalize(histogram, histogram, 0, histogramImage.rows, NORM_MINMAX);
for (int i = 0; i < histogram.rows; i++) {
// νμ€ν κ·Έλ¨ λ§λμ¬κ°νμ μμκ³Ό λμ Xμ’ν
float sx = i * gap;
float ex = (i + 1) * gap;
// μ¬κ°νμ μ’μΈ‘ νλ¨μ’νμ μ°μΈ‘ μλ¨ μ’ν
Point2f pt_Ib(sx, 0), pt_rt(ex, histogram.at<float>(i));
// μ¬κ°νμ΄ λμ΄ κ°μ κ°μ§λ©΄ μ¬κ°νμ κ·Έλ¦Ό
if (pt_rt.y > 0)
rectangle(histogramImage, pt_Ib, pt_rt, Scalar(0), -1);
}
// XμΆ κΈ°μ€μΌλ‘ μμμ λ€μ§μ (μμμμ μ’νκ³λ μλκ° μμ κ°μ κ°μ§λ―λ‘, μκ° μμ κ°μ κ°λ μ’νκ³λ‘ λ³ν)
flip(histogramImage, histogramImage, 0);
}
// νμ€ν κ·Έλ¨1 보기
void ShowHistogram1() {
auto fileName = OpenFileDialog();
image = imread(fileName, IMREAD_GRAYSCALE);
if (image.empty()) {
cout << "νμΌ μ½κΈ° μ€ν¨" << endl;
return;
}
CalcHistogram(image, histogram, 256);
cout << histogram.t() << endl;
GetHistogramImage(histogram, histogramImage);
imshow("μλ³Έ μμ 1", image);
imshow("νμ€ν κ·Έλ¨ 1", histogramImage);
waitKey();
}
// νμ€ν κ·Έλ¨2 보기
void ShowHistogram2() {
auto fileName2 = OpenFileDialog();
image2 = imread(fileName2, IMREAD_GRAYSCALE);
if (image2.empty()) {
cout << "νμΌ μ½κΈ° μ€ν¨" << endl;
return;
}
CalcHistogram(image2, histogram2, 256);
cout << histogram2.t() << endl;
GetHistogramImage(histogram2, histogramImage2);
imshow("μλ³Έ μμ 2", image2);
imshow("νμ€ν κ·Έλ¨ 2", histogramImage2);
waitKey();
}
// ννν μμ
- ννν κΈ°λ²μΌλ‘ λͺ
μ λΆν¬κ° λΉμ½ν μμμ κ· μΌνκ² λ§λ¬
void CalcNormalizedCumulativeFrequency(Mat histogram, Mat& histogramSum) {
// νμ€ν κ·Έλ¨κ°μ μ μ₯ν MatμΈμ€ν΄μ€ μμ±, 0μΌλ‘ μ΄κΈ°ν
histogramSum = Mat(histogram.rows, 1, CV_32F, Scalar(0));
// νμ€ν κ·Έλ¨μ λμ ν©μ κ³μ°
float sum = 0;
for (int i = 0; i < histogram.rows; i++) {
sum += histogram.at<float>(i);
histogramSum.at<float>(i) = sum;
}
// μ κ·ν
for (int i = 0; i < histogramSum.rows; i++)
histogramSum.at<float>(i) = histogramSum.at<float>(i) / sum * 255.0;
}
// λ λμ CPUμμμ λͺ¨λ ννν ν λ€μ, νννλ CPUλ₯Ό μννννμ¬ λ£©μ
ν
μ΄λΈμ λ§λ€κ³ λ λμ 맀ννλ ν¨μ
void HistogramEqualizing() {
// 1. λ λ μμ ννν μμ
// νμ€ν κ·Έλ¨ μμ±
CalcHistogram(image, histogram, 256);
// λμ λΉλ μ κ³μ° λ° μ κ·ν
CalcNormalizedCumulativeFrequency(histogram, histogramSum);
// μ κ·νλ λμ λΉλ μλ₯Ό κΈ°λ°μΌλ‘ κΈ°μ‘΄μ νμλ₯Ό λ³ν
// νμκ° μ μ΄
tmp = Mat(image.size(), image.type());
for (int i = 0; i < image.rows; i++)
for (int j = 0; j < image.cols; j++)
tmp.at <uchar>(i, j) = (uchar)histogramSum.at<float>(image.at<uchar>(i, j));
// γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘
// 2, cpu μ¬μ§ ννν μμ
// νμ€ν κ·Έλ¨ μμ±
CalcHistogram(image2, histogram2, 256);
// λμ λΉλ μ κ³μ° λ° μ κ·ν
CalcNormalizedCumulativeFrequency(histogram2, histogramSum2);
// μ κ·νλ λμ λΉλ μλ₯Ό κΈ°λ°μΌλ‘ κΈ°μ‘΄μ νμλ₯Ό λ³ν
// νμκ° μ μ΄
tmp2 = Mat(image2.size(), image2.type());
for (int i = 0; i < image2.rows; i++)
for (int j = 0; j < image2.cols; j++)
tmp2.at <uchar>(i, j) = (uchar)histogramSum2.at<float>(image2.at<uchar>(i, j));
// γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘γ
‘
}
// μνννμ 룩μ
ν
μ΄λΈ 맀ννλ ν¨μ
void GetResult()
{
// 3. cpu μ¬μ§ μννν μμ
// νμ€ν κ·Έλ¨ μμ±
CalcHistogram(tmp2, histogramNew, 256);
int image_1 = 254;
int image_2 = 255;
// μ κ·νλ κ°μ λͺ
μμ ν΄λΉνλ κ°μ μν¨μλ‘ λ§λ€μ΄μ
// histogramNewμ μν¨μλ‘ λ§€νλ μννν ν
μ΄λΈμ μ μ₯νλ€.
while (image_1 >= 0) { // λͺ¨λ 맀ννλ©΄ μ€ν (image_1 μ΄ 0μ΄λλ©΄ μν¨μ 맀νμ΄ λλλ€.)
for (int i = histogramSum2.at<float>(image_1); i <= histogramSum2.at<float>(image_2); i++)
histogramNew.at<float>(i) = image_2;
image_2 = image_1--;
}
/*
image_2 = 255 -> 254 -> 253 ------> 1
image_1 = 254 -> 253 -> 252 ------> 0
new = 0 -> 254 -> 253 ------------> 2
*/
// 4. 룩μ
-ν
μ΄λΈ 맀ν μμ
// μ κ·νλ λμ λΉλ μλ₯Ό κΈ°λ°μΌλ‘ κΈ°μ‘΄μ νμλ₯Ό λ³ν
// νμκ° μ μ΄
auto result = Mat(tmp.size(), tmp.type());
// 룩μ
-ν
μ΄λΈμ ν΅ν΄ λ λμ μ¬μ§μ λͺ
μΈννλ€.
for (int i = 0; i < tmp.rows; i++)
for (int j = 0; j < tmp.cols; j++)
result.at <uchar>(i, j) = (uchar)histogramNew.at <float>(tmp.at<uchar>(i, j));
// μ²λ¦¬λ μμμ νμ€ν κ·Έλ¨ κ³μ°
CalcHistogram(result, histogramNew, 256);
GetHistogramImage(histogramNew, histogramImage);
// λͺ
μΈν κ²°κ³Ό μΆλ ₯
imshow("λͺ
μΈν κ²°κ³Ό μμ", result);
imshow("λͺ
μΈν κ²°κ³Ό νμ€ν κ·Έλ¨", histogramImage);
waitKey();
}
int main()
{
ShowHistogram1(); // νμ€ν κ·Έλ¨1 보기
ShowHistogram2(); // νμ€ν κ·Έλ¨2 보기
HistogramEqualizing(); // λ μμ ννν μμ
GetResult(); // μνννλ‘ λ£©μ
ν
μ΄λΈ μμ± ν λ λ μμμ 맀ν
}
728x90
λ°μν
'π Programming > OpenCV' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[OpenCV] μμ μ€μΌμΌλ§(Scailing) (0) | 2020.12.30 |
---|---|
[μμ μ²λ¦¬] λ―ΈλΆμ μ΄μ©ν μ£μ§(Edge) κ²μΆ (0) | 2020.12.29 |
[μμ μ²λ¦¬] κ°λ¨ν μ£μ§(Edge) κ²μΆ κΈ°λ² (0) | 2020.12.29 |
[μμ μ²λ¦¬] νμ μ²λ¦¬ κΈ°λ² νμ©κ³Ό κ°μ°μμ νν°(Gaussian Filter) (0) | 2020.12.29 |
[μμ μ²λ¦¬] νμ μ²λ¦¬μ μ리μ κ²½κ³ λΆλΆ μ²λ¦¬ (1) | 2020.12.29 |