Created
August 2, 2020 16:29
-
-
Save terakun/90801f85e2ae9d64a2b439276dac6e83 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <opencv2/core/core.hpp> | |
#include <opencv2/imgproc/imgproc.hpp> | |
#include <opencv2/highgui/highgui.hpp> | |
#include <iostream> | |
#include <vector> | |
#include <array> | |
#include <stdio.h> | |
using namespace std; | |
using namespace cv; | |
void make_histogram_img(const cv::Mat &,cv::Mat &); | |
void histogram_matching(const cv::Mat &ref_img,const cv::Mat &src_img,cv::Mat &dst_img); | |
int main(){ | |
cv::Mat ref_img,src_img , dst_img; | |
ref_img = imread( "./image4.jpg",0 ); | |
src_img = imread( "./image5.jpg",0 ); | |
histogram_matching(ref_img,src_img,dst_img); | |
cv::Mat ref_hist_img,src_hist_img,dst_hist_img; | |
make_histogram_img(ref_img,ref_hist_img); | |
make_histogram_img(src_img,src_hist_img); | |
make_histogram_img(dst_img,dst_hist_img); | |
cv::imshow("source image",src_img); | |
cv::imshow("source histogram",src_hist_img); | |
cv::imwrite("image4_hist.jpg",src_hist_img); | |
waitKey(0); | |
cv::imshow("reference image",ref_img); | |
cv::imshow("reference histogram",ref_hist_img); | |
cv::imwrite("image5_hist.jpg",ref_hist_img); | |
waitKey(0); | |
cv::imshow("destination image",dst_img); | |
cv::imshow("destination histogram",dst_hist_img); | |
cv::imwrite("dst.jpg",dst_img); | |
cv::imwrite("dst_hist.jpg",dst_hist_img); | |
waitKey(0); | |
return 0; | |
} | |
void make_histogram_img(const cv::Mat &src_img,cv::Mat &hist_img){ | |
int histSize = 256; | |
float range[] = { 0, 256 } ; | |
const float* histRange = { range }; | |
bool uniform = true; bool accumulate = false; | |
cv::Mat hist; | |
cv::calcHist( &src_img, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate ); | |
int hist_w = 512, hist_h = 400; | |
int bin_w = cvRound( (double) hist_w/histSize ); | |
hist_img = cv::Mat(hist_h,hist_w,CV_8UC3,cv::Scalar(0,0,0)); | |
cv::normalize(hist, hist, 0, hist_img.rows, NORM_MINMAX, -1, Mat() ); | |
for( int i = 1; i < histSize; i++ ){ | |
line( hist_img, Point( bin_w*(i-1), hist_h - cvRound(hist.at<float>(i-1)) ) , | |
Point( bin_w*(i), hist_h - cvRound(hist.at<float>(i)) ), | |
Scalar( 255, 255, 255), 2, 8, 0 ); | |
} | |
} | |
void histogram_matching(const cv::Mat &ref_img,const cv::Mat &src_img,cv::Mat &dst_img){ | |
std::vector<int> g_ref,g_src; | |
cv::Mat ref_hist,src_hist; | |
constexpr int histSize = 256; | |
float range[] = { 0, histSize } ; | |
const float* histRange = { range }; | |
bool uniform = true; bool accumulate = false; | |
cv::calcHist( &src_img, 1, 0, Mat(), src_hist, 1, &histSize, &histRange, uniform, accumulate ); | |
cv::calcHist( &ref_img, 1, 0, Mat(), ref_hist, 1, &histSize, &histRange, uniform, accumulate ); | |
src_hist /= src_img.size().area(); | |
ref_hist /= ref_img.size().area(); | |
std::array<double,histSize> src_cdf,ref_cdf; | |
src_cdf[0] = src_hist.at<float>(0,0); | |
ref_cdf[0] = ref_hist.at<float>(0,0); | |
for(int i=1;i<histSize;++i){ | |
src_cdf[i] = src_cdf[i-1] + src_hist.at<float>(0,i); | |
ref_cdf[i] = ref_cdf[i-1] + ref_hist.at<float>(0,i); | |
} | |
std::array<int,histSize> lookuptable; | |
for(int i=0;i<histSize;++i){ | |
double min_v = 1.0e10; | |
int min_j; | |
for(int j=0;j<histSize;++j){ | |
if(min_v > std::abs(src_cdf[i]-ref_cdf[j])){ | |
min_v = std::abs(src_cdf[i]-ref_cdf[j]); | |
min_j = j; | |
} | |
} | |
lookuptable[i] = min_j; | |
} | |
dst_img = cv::Mat(src_img.size(),src_img.type()); | |
for(int r=0;r<src_img.rows;++r){ | |
const uchar *src_img_ptr = src_img.ptr<uchar>(r); | |
uchar *dst_img_ptr = dst_img.ptr<uchar>(r); | |
for(int c=0;c<src_img.cols;++c){ | |
dst_img_ptr[c] = lookuptable[src_img_ptr[c]]; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment