C++ VS2010
Opencv 2.4.9
参考自:https://blog.csdn.net/u013263891/article/details/82987417
参考自:https://www.cnblogs.com/brucemu/archive/2013/10/17/3374558.html
#include
#include
using namespace std;
using namespace cv;
void main()
{
//以灰度图读取图片 使其通道为1
Mat img = imread("Fig0316(4)(bottom_left).tif",0);
int gray[256]={0};//记录灰度级别下的像素个数
int mn;//像素总数
double r_prob[256]={0};//输入图像的概率
double pdf[256]={0};//累积概率密度
double r[256]={0};//r与s的映射
double s_prob[256]={0};//均衡化之后的概率
Mat img_temp = img.clone();
//得出每个灰度级下像素个数
for(int i = 0;i<img.rows;i++)
{
for(int j = 0;j<img.cols;j++)
{
int gray_value = img.at<uchar>(i,j);
gray[gray_value]++;
}
}
//得出每个灰度级概率分布
mn = img.rows*img.cols;
for(int i = 0;i<256;i++)
{
r_prob[i] = ((double)gray[i])/mn;
}
//得出每个灰度级概率密度函数
pdf[0] = r_prob[0];
for(int i = 1;i<256;i++)
{
pdf[i] = pdf[i-1] + r_prob[i];
}
//计算直方图均衡映射的各个灰度级个数
for(int i = 0;i<256;i++){
r[i] = (int)cvRound(255*pdf[i]);
}
//重新绘制图片 根据上述的灰度值均衡的结果
for(int i = 0;i<img.rows;i++)
{
for(int j = 0;j<img.cols;j++)
{
int gray_value = img.at<uchar>(i,j);
img_temp.at<uchar>(i,j) = r[gray_value];
}
}
imshow("原图像",img);
imshow("Mine_code",img_temp);
//直方图显示
int bins=256;
int hist_size[]={bins};
float range[]={0,256};
const float* ranges[]={range};
cv::Mat histsrc,histdst;
int channels[]={0};
/*
const Mat* images:输入图像
int nimages:输入图像的个数
const int* channels:需要统计直方图的第几通道
InputArray mask:掩膜,,计算掩膜内的直方图 ...Mat()
OutputArray hist:输出的直方图数组
int dims:需要统计直方图通道的个数
const int* histSize:指的是直方图分成多少个区间,就是 bin的个数
const float** ranges: 统计像素值得区间
bool uniform=true::是否对得到的直方图数组进行归一化处理
bool accumulate=false:在多个图像时,是否累计计算像素值得个数
*/
calcHist(&img,1,channels,Mat(),histsrc,1,hist_size,ranges,true,false);
calcHist(&img_temp,1,channels,Mat(),histdst,1,hist_size,ranges);
cout<<histsrc.size()<<endl;
int scale=1;
Mat srcImage(256*scale,256,CV_8U,cv::Scalar(0));
Mat dstImage(256*scale,256,CV_8U,cv::Scalar(0));
double maxValue=0;
double minValue=0;
minMaxLoc(histsrc,&minValue,&maxValue,0,0);
cout<<sum(histsrc)<<endl;
//int hpt=saturate_cast(255);
int hpt=255;
cout<<"原直方图"<<endl;
for(int i=0;i<256;i++){
float binValue=histsrc.at<float>(i);
cout<<binValue<<" ";
int realValue=saturate_cast<int>(binValue*hpt/maxValue);
rectangle(srcImage,Point(i*scale,255),Point((i+1)*scale-1,256-realValue),
Scalar(255));
}
minMaxLoc(histdst,&minValue,&maxValue,0,0);
hpt=saturate_cast<int>(255);
cout<<"直方图均衡后的直方图"<<endl;
for(int i=0;i<256;i++){
float binValue=histdst.at<float>(i);
cout<<binValue<<" ";
int realValue=saturate_cast<int>(binValue*hpt/maxValue);
rectangle(dstImage,Point(i*scale,255),Point((i+1)*scale-1,256-realValue),
Scalar(255));
}
imshow("srcImage",srcImage);
imshow("dstImage",dstImage);
waitKey(0);
}
void histo_match()
{
Mat src=cv::imread("Fig0308(a)(fractured_spine).tif",0);
int gray[256]={0};//记录灰度级别下的像素个数
int mn=src.cols*src.rows;//像素总数
double r_pdf[256]={0};//输入图像的概率
double r_cdf[256]={0};//累积概率密度
double r[256]={0};//对应的s T(r)
int z[256]={0};//对应的G(z)
double z_pdf[256];//pz(z)
double z_cdf[256]={0};//z的累积分布概率
cv::Mat dst=src.clone();
cv::Mat spe=src.clone();
//记录灰度级别下的像素个数
for(int row=0;row<src.rows;row++){
for(int col=0;col<src.cols;col++){
int g=src.at<uchar>(row,col);
gray[g]++;
}
}
//统计高斯函数直方图像素总数(虚拟)
z_pdf[0] = 0;
double sum=0;
for(int i=0;i<256;i++){
double r=(double)i/255.0;
z_pdf[i+1]=twoModeGauss(r);
sum+=z_pdf[i+1];
}
//计算pr(r) pz(z)概率密度函数
for(int i = 0;i<256;i++)
{
r_pdf[i] = ((double)gray[i])/mn;
z_pdf[i] = z_pdf[i]/sum;
}
//计算r和z的cdf 累计分布函数
z_cdf[0]=z_pdf[0];
r_cdf[0]=r_pdf[0];
for(int i=1;i<256;i++){
r_cdf[i]=r_cdf[i-1]+r_pdf[i];
z_cdf[i]=z_cdf[i-1]+z_pdf[i];
}
//根据变换函数计算相应灰度值、
for(int i=0;i<256;i++)
{
int s = cvRound(255*r_cdf[i]);
r[i] = s;
int z_value = cvRound(255*z_cdf[i]);
z[i] = z_value;
}
//直方图均衡化
for(int row = 0;row<src.rows;row++)
{
for(int col = 0;col<src.cols;col++)
{
dst.at<uchar>(row,col) = r[src.at<uchar>(row,col)];
}
}
//直方图规定
for(int row = 0;row<src.rows;row++)
{
for(int col = 0;col<src.cols;col++)
{
int value = src.at<uchar>(row,col);
for(int i = 0;i<256;i++)
{
if(z[value] == r[i])
{
spe.at<uchar>(row,col) = i;
}
}
}
}
//显示图片
cv::imshow("src",src);
cv::imshow("dst",dst);
cv::imshow("spe",spe);
//显示直方图
Mat src_histo = showHisto(src);
imshow("原图像直方图",src_histo);
Mat dst_histo = showHisto(dst);
imshow("直方图均衡图像直方图",dst_histo);
Mat sqe_histo = showHisto(spe);
imshow("直方图规定图像直方图",sqe_histo);
waitKey(0);
}
#include
#include
using namespace std;
using namespace cv;
int box_length = 13;
int box_center = (box_length-1)/2;
void localhisto(Mat &img)
{
int gray[256]={0};//记录灰度级别下的像素个数
int mn;//像素总数
double r_prob[256]={0};//输入图像的概率
double pdf[256]={0};//累积概率密度
double r[256]={0};//r与s的映射
double s_prob[256]={0};//均衡化之后的概率
for(int i = 0;i<img.rows;i++)
{
for(int j = 0;j<img.cols;j++)
{
int gray_value = img.at<uchar>(i,j);
gray[gray_value]++;
}
}
//得出每个灰度级概率分布
mn = img.rows*img.cols;
for(int i = 0;i<256;i++)
{
r_prob[i] = ((double)gray[i])/mn;
}
//得出每个灰度级概率密度函数
pdf[0] = r_prob[0];
for(int i = 1;i<256;i++)
{
pdf[i] = pdf[i-1] + r_prob[i];
}
//计算直方图均衡映射的各个灰度级个数
for(int i = 0;i<256;i++){
r[i] = (int)cvRound(255*pdf[i]);
}
//重新绘制图片 根据上述的灰度值均衡的结果
int gray_value = img.at<uchar>(box_center,box_center);
img.at<uchar>(box_center,box_center) = r[gray_value];
}
int main(){
cv::Mat src=cv::imread("Fig0326(a)(embedded_square_noisy_512).tif",0);
cv::Mat dst=src.clone();
Mat temp;
//512 512
for(int row = box_center;row<src.rows-box_center;row++){
for(int col = box_center;col<src.cols-box_center;col++)
{
temp = dst(Range(row-box_center,row+box_center),Range(col-box_center,col+box_center));
localhisto(temp);
dst(Range(row-box_center,row+box_center),Range(col-box_center,col+box_center)) = temp;
}
}
Mat histoglobal = src.clone();
Mat seconddst = src.clone();
for(int row = box_center;row<src.rows-box_center;row+=box_length){
for(int col = box_center;col<src.cols-box_center;col+=box_length)
{
temp = seconddst(Range(row-box_center,row+box_center),Range(col-box_center,col+box_center));
localhisto(temp);
seconddst(Range(row-box_center,row+box_center),Range(col-box_center,col+box_center)) = temp;
}
}
localhisto(histoglobal);
cv::imshow("原图像",src);
cv::imshow("局部均衡化",dst);
cv::imshow("局部均衡化(简化版会有棋盘效应)",seconddst);
cv::imshow("全局均衡化",histoglobal);
cv::waitKey(0);
return 0;
}
#include
#include
double getMean(double*r_pdf){
double m=0;
for(int i=0;i<256;i++)
m+=i*r_pdf[i];
return m;
}
double getVariance(double *r_pdf,double m)
{
double delta=0;
for(int i=0;i<256;i++)
if(r_pdf[i]!=0)
delta+=(pow((i-m),2)*r_pdf[i]);
return delta;
}
void init(double *r_pdf){
for(int i=0;i<256;i++){
r_pdf[i]=0;
}
}
void histStatistic(cv::Mat &src,int dim,float k0,float k1,float k2,float E){
if(dim%2==0){
dim = dim+1;
}
int width=src.rows;
int height=src.cols;
int mn=width*height;
double r_pdf[256]={};
for(int row=0;row<src.rows;row++){
for(int col=0;col<src.cols;col++){
int g=src.at<uchar>(row,col);
r_pdf[g]+=1.0/mn;
}
}
double mean=getMean(r_pdf);
double delta=getVariance(r_pdf,mean);
double delta1=std::sqrt(delta);
double mxy=0;
double deltaxy=0;
double local=dim*dim;
for(int i=dim/2;i<height-dim/2-1;i++)
{
for(int j=dim/2;j<width-dim/2;j++){
init(r_pdf);
//统计局部直方图
for(int p=j-dim/2;p<j+dim/2+1;p++){
for(int q=i-dim/2;q<i+dim/2+1;q++){
int g=src.at<uchar>(p,q);
r_pdf[g]+=1.0/local;
}
}
mxy=getMean(r_pdf);
deltaxy=getVariance(r_pdf,mxy);
double deltaxy1=sqrt(deltaxy);
if(mxy<=mean*k0&&deltaxy1<=k2*delta1&&deltaxy1>=k1*delta1){
src.at<uchar>(j,i)=src.at<uchar>(j,i)*E;
}
}
}
}
int main(){
cv::Mat src=cv::imread("Fig0327(a)(tungsten_original).tif",0);
cv::Mat dst;
dst=src.clone();
histStatistic(dst,7,0.4,0.02,0.4,10);
cv::imshow("src",src);
cv::imshow("dst",dst);
cv::waitKey(0);
}