2017-03-21 19:56:13 qq_34784753 阅读数 5658

直方图是数字图像处理中的一个重要的基础工具,在讨论各种空域图像处理之前,首先要十分清楚直方图的概念以及它的表示的意义。

直方图提供了图像的统计信息,为了理解多种空域增强技术的内涵提供了铺垫。此外,利用直方图操作也可以直接用于图像增强。目前大多数数字照相机都有显示所拍摄照片直方图的功能,直方图可以显示出整张照片的灰度分布情况,可以根据直方图所示的灰度分布判断图像曝光是否恰当,有助于拍摄前的各种参数中设置,如感光度、光圈、快门速度和曝光时间等。

1.灰度直方图

直方图是数字图像的统计表征量。对于一幅灰度图像,灰度直方图反映了图像中不同灰度像素出现的统计情况,描述了像素灰度的分布情况。数字图像的灰度直方图是一个一维离散函数,定义为


其中,rk表示第k个灰度级,nk表示灰度值为rk的像素在图像中出现的频数,L表示灰度级数。

在一幅图像中,灰度值为rk的像素出现的频数与像素总数的比值,称为“概率直方图”,可以表示为:


式中,n为图像中的像素总数,等号坐标实际上表示灰度级rk的概率分布。因此,在概率直方图中,所有灰度级的概率之和等于1.

图像的直方图的两个性质:

1.直方图表示一幅图像中不同灰度像素出现的统计信息,它只能反映该图像中不同灰度值出现的频数(概率),而不能表示出像素的位置等其他信息。

2.图像与直方图之间是多对一的映射关系,也就是说,不同的图像可能对应同一幅灰度直方图。

图像直方图在数字图像处理中的三个方面的应用:

a.直方图可以用于判断一幅图像是否合理的利用了全部可能的灰度级。直观上来说,如果一幅图像的像素值充分占有整个灰度级范围并且分布比较均匀,则这样的图像具有高对比度和多灰度阶。通过检查灰度直方图,可以确定设备参数调整方向,或者灰度级变换规则,如伽玛校正。

b.图像的视觉效果与其直方图之间存在对应关系,改变直方图的形状对图像产生对应的影响。通过直方图可以推断出图像的一些性质:明亮图像的直方图倾向于灰度级高的一侧,灰暗图像的直方图倾向于灰度级低的一侧;低对比度图像的直方图集中于灰度级中很窄的范围,高对比度图像的直方图覆盖的灰度级很宽而且像素的分布比较均匀。因此,通过处理直方图可以起到图像增强的作用。

c.利用直方图可以在图像分割中确定合适的阈值,并且能够根据直方图区域对像素进行统计。

2.累积直方图

累积直方图实际上就是概率直方图p(rk)关于灰度级rk的累积概率分布,定义为:


其中,rk表示第k个灰度级,nk为频数,n为总数,c(rk)表示灰度值落在区间[0,rk]内的像素在图像中出现的总概率,L表示灰度级数。需要注意的是,累积直方图一定是递增的(不一定严格递增),且第L个灰度级的累积概率值一定等于1.

3.彩色图像的分量直方图

上面说的直方图都是针对灰度图像而言的,下面主要来考虑一下彩色图像的情况。因为在彩色图像中,每个像素的颜色是有3个分量数值组成的一个向量。因此所谓的彩色图像的直方图,其实是对图像中所有像素的R,G,B分量分别统计得到的3个分量的直方图。3个分量的黑白印刷效果实际上就是3个灰度图像,下面考虑如何将一幅彩色图像转换成为灰度图像的方法。

如果直接分别提取R,G,B三个分量中的一个分量作为结果图像的灰度,其他两个分量在置为与选定分量同等大小的值,这就类似于黑白印刷的效果。但是这种方式处理有相应缺点,显示效果并不是十分理想,毕竟其中的两个分量被忽略掉了,而它们对于最终的显示效果也有贡献。因此一般会采用下面的方法,大致有3种。

a.平均值法:

每个像素的三原色值等于红绿蓝3个分量的平均值,这样一来,结果图像中的像素值构成也就均匀的考虑到了3个分量的影响,公式可以表示为:


b.最大值法:

每个像素的三原色值等于红绿蓝3个颜色的最大值,公式为:


c.加权平均值法:

加权平均值法中给予红绿蓝3个分量不同的权值,然后进行相加,公式如下:


人眼对于三原色的敏感程度从高到低分别是绿、红、蓝,所以三原色权值的取值关系应该是WG>WR>WB,由YUV颜色空间可知,当R=G=B=0.299R+0.587G+0.114B时,能够得到最合适的灰度图像。

4.直方图处理:

直方图处理也是一种点处理方法,它通过对灰度直方图进行变换有效的实现图像增强。直方图处理主要有直方图均衡化直方图规定化两种方法。直方图均衡化是通过灰度级变换将输入图像变换为具有均匀分布直方图的图像。更一般的情况,直方图规定化是指通过灰度级变换将输入图像转换为具有特定分布直方图的图像。

a.基础理论

直方图处理的作用是通过是直方图服从均匀分部或者其他特定的函数形式,从而扩展灰度级的动态范围。提高图像的对比度、增强局部细节等等。

设r表示输入图像的灰度级,概率分布率为Pr(r),s表示输出图像的灰度级,其概率分布律为Ps(s),其中0<=r,s<=1,直方图处理就是选取灰度级变换函数,使得

s = T(r)

式中,T(r)为变换函数,T(r)的选取应该满足下面的条件:

(1).T(r)在区间0 <= r <= 1内为严格单调递增函数

(2).对于0 <= r <=1,有0 <= T(r) <=1

第1个条件保证了灰度级从暗到亮的次序不变,并且保证了反函数的存在;第二个条件保证了输出灰度级与输入灰度级具有相同的灰度级范围。满足上述条件的反函数表示为:

r = T^(-1)(s)

反函数同样满足上述的两个条件。

b.直方图均衡化

当直方图中像素值集中在狭窄的灰度级范围内或分布极不均匀时,图像呈现较差的对比度。由于一幅适当对比度图像的直方图具有较宽的灰度级范围,且分布较为平坦,

直方图均衡化的目的是将直方图的灰度级概率分布变换为均匀分布。

对于L个灰度级的数字图像,直方图均衡化后的概率分布率做不到完全服从均匀分布。设第k个灰度级为rk,具有灰度值rk的像素数为nk,像素总数为n,直方图均衡化的具体可执行的步骤如下:

(1).计算输入图像灰度级rk的概率分布律Pr(rk),统计各灰度级rk的像素出现的概率为:


 (2).计算输入图像灰度级rk的累积概率分布率Fr(rk):

(3).确定输入灰度级与输出灰度级之间的映射关系rk→sk,将输入图像中的rk映射到输出图像中灰度级为sk的对应像素中

(4).统计输出图像各灰度级sk的像素数,并计算输出图像灰度级sk的概率分布率Ps(sk)。

需要注意的是,在灰度级为离散形式时,灰度级映射后的灰度值sk一般并非落在量化的灰度级上,因此将灰度值sk近似为最接近的量化灰度级sk。因此直方图中的同一灰度级的像素不能拆分,而不同灰度级的像素通常会发生合并,因此,造成所使用的灰度级数减少,从而造成细节信息的丢失

最后需要说明,直方图均衡化的目的是一幅图像的像素值占有全部可能的灰度级且分布的尽可能均匀,尽管能够从视觉效果上提高图像的对比度,但是,由于直方图中概率较小的灰度级合并为更少的几个或一个灰度范围内,从而降低了图像的灰度分辨率,且某些细节信息处于概率较小的灰度级中,这样的灰度级归并到其他灰度级中,从而造成图像细节信息的丢失。

因此,已有的研究表明,一种好的图像增强(复原)的算法应该使得处理后图像的直方图与源图像的直方图在总体形状上保持一致。因此,直方图均衡化的主要问题是造成了直方图的形状发生了失真,从而使得处理后的图像看起来缺乏真实性和自然性。

b.直方图规定化

上面介绍的直方图均衡化能够增强图像的对比度,然而却无法控制具体的增强效果,更一般的情况是要求图像具有特定的直方图,以便于有选择的对图像中某个特定的灰度级范围进行增强,或使其满足后续处理的特定需求。

直方图规定划的目的是是将具有一直直方图的图像变换为具有某种特定形状直方图或者用户交互指定形状直方图的图像,因而也称为“直方图匹配”

可以看出,直方图均匀化是直方图规定化的特例,因为它将输入图像的直方图变换为服从均匀分布的直方图

对于数字图像,由于直方图是离散化的,不同灰度级的像素可以合并,同一灰度级的像素不能拆分,因此,不同的映射关系,会产生不同的规定化结果。设数字图像具有L个灰度级,输入图像的灰度级为rk,具有灰度值rk的像素数为nk,直方图规定划具体可执行步骤大致如下:

(1).对输入图像的概率直方图Pr(rk)进行直方图均衡化,也就是计算Pr(rk)的累积直方图


(2).对规定直方图Pv(vj)进行直方图均衡化,即计算规定化累积直方图:


(3).根据前向映射sk→vt或者向后映射vt→sk临近原则将输入灰度级映射到新的灰度级,也就是寻找k和l满足条件:

(4).确定输入灰度级与输出灰度级之间的映射关系rk→vk,将输入图像中灰度级为rk的像素映射到输出图像中灰度级为vk的对应像素。

(5).统计输出图像各灰度级vk的像素个数,并计算输出图像的概率直方图。

2019-01-16 21:12:31 qq_42887760 阅读数 192

直方图概念

在这里插入图片描述
上述直方图概念是基于图像像素值,其实对图像梯度、每个像素的角度、等一切图像的属性值,我们都可以建立直方图。这个才是直方图的概念真正意义,不过是基于图像像素灰度直方图是最常见的。
直方图最常见的几个属性:

  • dims:要收集数据的参数数量。 在我们的示例中,dims = 1,因为我们只计算每个像素的强度值(在灰度图像中)。
  • bin:它是每个暗淡的细分数量。 在我们的示例中,bin = 16
  • range:要测量的值的限制。 在这种情况下:范围= [0,255]

API学习

  • split(// 把多通道图像分为多个单通道图像
    const Mat &src, //输入图像
    Mat* mvbegin)// 输出的通道图像数组

  • calcHist(
    const Mat* images,//输入图像指针
    int images,// 图像数目
    const int* channels,// 通道数,要计算的通道数的下标,可以传一个数组 {0, 1} 表示计算第0通道与第1通道的直方图,此数组长度要与histsize ranges 数组长度一致
    InputArray mask,//输入mask,可选。如有,则表示只计算mask元素值为255的位置的直方图
    OutputArray hist,//输出的直方图数据
    int dims,// 维数
    const int* histsize,// 直方图级数 ,对应 bins
    const float* ranges,// 值域范围
    bool uniform,// true by default 是否归一化到 0-1 之间
    bool accumulate// false by defaut
    )

程序代码

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
    Mat src;
	// 1. 加载源图像
    src=imread("E:/Experiment/OpenCV/Pictures/dog2.jpg");
	imshow("input Image",src);

    // 2. 在R、G、B平面中分离源图像,把多通道图像分为多个单通道图像。使用OpenCV函数cv::split。
    vector<Mat> bgr_planes;
    split(src, bgr_planes);// 把多通道图像分为多个单通道图像

    printf("channels=%d\n", bgr_planes.size());//3通道,所以size也是3
    imshow("channels_b", bgr_planes[0]);
    imshow("channels_g", bgr_planes[1]);
    imshow("channels_r", bgr_planes[2]);

    // 3. 现在我们准备开始为每个平面配置直方图。 由于我们正在使用B,G和R平面,我们知道我们的值将在区间[0,255]范围内
    int histBins = 256;//建立箱数(5,10 ......)
    float range[] = { 0, 256 };//设置值的范围(在0到255之间)
    const float * histRanges = range;//注意:函数形参 float ** 与 const float ** 是两种不同数据类型。
	bool uniform = true, accumulate = false;//我们希望我们的箱子具有相同的尺寸(均匀)并在开头清除直方图
    Mat b_hist, g_hist, r_hist;//calcHist计算出来的Mat中元素的最大值可能上几千,所以最好归一化后再绘制直方图
    //使用OpenCV函数cv::calcHist计算直方图:
	calcHist(&bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histBins, &histRanges, uniform, accumulate);//计算直方图
    calcHist(&bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histBins, &histRanges, uniform, accumulate);
    calcHist(&bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histBins, &histRanges, uniform, accumulate);

    // 4. 归一化
    int hist_cols = 400;
    int hist_rows = 512;
    int bin_w = hist_rows / histBins;
    /*
        normalize(  // normalize函数作用为 归一化数据
            InputArray src, // 输入数组
            InputOutputArray dst, // 输出数组,数组的大小和原数组一致
            double alpha = 1, // 1,用来规范值,2.规范范围,并且是下限
            double beta = 0, // 只用来规范范围并且是上限
            int norm_type = NORM_L2, // 归一化选择的数学公式类型
            int dtype = -1, // 当为负,输出在大小深度通道数都等于输入,当为正,输出只在深度与输如不同,不同的地方由dtype决定
            InputArray mask = noArray() // 掩码。选择感兴趣区域,选定后只能对该区域进行操作
        );

        值归一化举例说明:   参考博客 https://blog.csdn.net/cosmispower/article/details/64457406
            src={10,23,71},参数 beta 设为0,值的范围为 0-参数alpha 设置的值,例子中alpha设置为1
            NORM_L1运算后得到   dst={0.096,0.221,0.683}       NORM_* 的归一化公式参考上述博客
            NORM_INF运算后得到  dst={0.141,0.324,1}
            NORM_L2运算后得到   dst={0.133,0.307,0.947}
            NORM_MINMAX运算得到 dst={0,0.377,1}             P = Ak / (max(Ai)-min(Ai))  Ak等于最大最小Ai时,不按此公式计算,P直接等于1, 0

        范围归一化时,beta必有值不等于0,范围为 alpha-beta ,alpha为下限(可为0也可非0),beta为上限
    */
	//请注意,在绘制之前,我们首先对直方图进行cv :: normalize,使其值落在输入参数指示的范围内:
    normalize(b_hist, b_hist, 0, hist_cols, NORM_MINMAX, -1, Mat());//b_hist中元素的值转换到 0-hist_cols 之间
    normalize(g_hist, g_hist, 0, hist_cols, NORM_MINMAX, -1, Mat());
    normalize(r_hist, r_hist, 0, hist_cols, NORM_MINMAX, -1, Mat());//传参 0, hist_cols 或 hist_cols, 0 结果一致

    // 5. 绘制直方图
    Mat histImage(hist_rows, hist_cols, CV_8UC3, Scalar(0, 0, 0));
    for (int i = 1; i < histBins; i++)
    {
        // cvRound 四舍五入,返回整型值
        line(histImage, Point((i - 1)*bin_w, hist_cols - cvRound(b_hist.at<float>(i - 1))),
            Point(i*bin_w, hist_cols - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2, LINE_AA);
        line(histImage, Point((i - 1)*bin_w, hist_cols - cvRound(g_hist.at<float>(i - 1))),
            Point(i*bin_w, hist_cols - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2, LINE_AA);
        line(histImage, Point((i - 1)*bin_w, hist_cols - cvRound(r_hist.at<float>(i - 1))),
            Point(i*bin_w, hist_cols - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2, LINE_AA);
    }
	// 6. 最后,我们显示直方图并等待用户退出:
    imshow("histImage", histImage);

    waitKey(0);
	return 0;
}

运行结果

在这里插入图片描述

参考代码

  1. https://blog.csdn.net/huanghuangjin/article/details/81173895
  2. https://blog.csdn.net/LYKymy/article/details/83189170
  3. https://blog.csdn.net/u011574296/article/details/73381576
2019-01-21 22:50:36 qq_34814092 阅读数 283

Java OpenCV-4.0.0 图像处理19 直方图计算

Java OpenCV-4.0.0 直方图计算

其实对图像梯度、每个像素的角度、等一切图像的属性值,我们都可以建立直方图。这个才是直方图的概念真正意义,不过是基于图像像素灰度直方图是最常见的。
直方图最常见的几个属性:
dims 表示维度,对灰度图像来说只有一个通道值dims=1
bins 表示在维度中子区域大小划分,bins=256,划分为256个级别
range 表示值得范围,灰度值范围为[0~255]之间

split(// 把多通道图像分为多个单通道图像
const Mat &src, //输入图像
Mat* mvbegin)// 输出的通道图像数组

calcHist(
const Mat* images,//输入图像指针
int images,// 图像数目
const int* channels,// 通道数
InputArray mask,// 输入mask,可选,不用
OutputArray hist,//输出的直方图数据
int dims,// 维数
const int* histsize,// 直方图级数
const float* ranges,// 值域范围
bool uniform,// true by default
bool accumulate// false by defaut
)

package com.xu.opencv;

import java.util.LinkedList;
import java.util.List;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

/**  
 * 
 * @Title: Image.java   
 * @Description: OpenCV-4.0.0 测试文件
 * @Package com.xu.test   
 * @author: xuhyacinth     
 * @date: 2019年5月7日12:13:13   
 * @version: V-1.0.0 
 * @Copyright: 2019 xuhyacinth
 *
 */
public class Image {

	static {
		//在使用OpenCV前必须加载Core.NATIVE_LIBRARY_NAME类,否则会报错
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
	}

	public static void main(String[] args) {
		calcHist();
	}
	
	/**
	 * OpenCV-4.0.0 直方图计算 
	 * @return: void  
	 * @date: 2019年5月7日12:16:55
	 */
	public static void calcHist() {
		Mat src=Imgcodecs.imread("C:\\Users\\Administrator\\Pictures\\3.jpeg");
		Mat gray = new Mat();
		//1 图片灰度化
		Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);
		List<Mat> matList = new LinkedList<Mat>();
		matList.add(gray);
		Mat histogram = new Mat();
		MatOfFloat ranges=new MatOfFloat(0,256);
		MatOfInt histSize = new MatOfInt(255);
		//2 计算直方图
		Imgproc.calcHist(matList,new MatOfInt(0),new Mat(),histogram,histSize ,ranges);
		//3 创建直方图面板
		Mat histImage = Mat.zeros( 100, (int)histSize.get(0, 0)[0], CvType.CV_8UC1);
		//4 归一化直方图                     
		Core.normalize(histogram, histogram, 1, histImage.rows() , Core.NORM_MINMAX, -1, new Mat() );   
		//5 绘制几何直方图
		for( int i = 0; i < (int)histSize.get(0, 0)[0]; i++ ){                   
			Imgproc.line(histImage,new org.opencv.core.Point(i, histImage.rows()),new org.opencv.core.Point(i, histImage.rows()-Math.round( histogram.get(i,0)[0])) ,new Scalar( 255, 255, 255),1, 8, 0 );
		}
		HighGui.imshow("直方图计算", histImage);
		HighGui.waitKey(0);
	}

}


OpenCV-4.0.0 直方图计算

2017-11-09 21:46:24 qq_17828675 阅读数 4003

灰度直方图

  • 概念
    对应每一个灰度值,统计该灰度值的像素数,据此绘制的像素数-灰度值图形。

直方图均衡化(histogram equalization)

  • 意义

    得到灰度直方图均匀分布的新图像,灰度分布区域均匀,图像所占的像素灰度间距拉大,加大图像反差,改善图像视觉效果,达到增强效果。

  • 步骤

    1. 计算原始图像直方图。
      h(rk)=nkP(rk)=nk/n
    2. 计算直方图累计分布曲线。
      T(rk)=j=0kPr(rj)=j=0knj/n
    3. 用累计分布曲线做变换函数进行图像灰度变换。
      sk=levelT(rk)

      level:灰度等级,例如256。
  • 效果

    histogram equalization

直方图规则化(histogram specification)

  • 概念

    得到具有特定形状的直方图的图像。

  • 原理

    对原始图像进行直方图均衡化处理.

    sk=T(rk)=j=0kPr(rj)=j=0knj/n

    对于目标图像也采用同样的方法进行均衡化处理.
    vk=G(rk)=j=0kPz(zi)=j=0kni/n

    由于对目标图像和原始图像都进行了均衡化处理,因此具有相同的分布密度,即
    sk=vk

    因而可以用原始图像均衡化以后的灰度级s代表v,即
    zk=G1(vk)=G1(sk)=G1(T(rk))

    所以可以依据原始图像均衡化后的图像的灰度值得到目标图像的灰度级z。

  • 步骤

    1. 计算原始图像(hist),参考图像(hisRef)直方图。
      h(rk)=nkP(rk)=nk/n
    2. 计算原始图像(cdf),参考图像(cdfRef)直方图累计分布曲线。
      T(rk)=j=0kPr(rj)=j=0knj/n
    3. 原始图像累计分布曲线对应灰度级用参考图像累计分布曲线最相近点处灰度级代替。
  • 效果

    histogram specification

code

clear all
%% ref picture
imRef=imread('1.jpg');%读取图像 
imRef=rgb2gray(imRef);
histRef= imhist(imRef);
cdfRef= cumsum(histRef) / numel(imRef);
%% picture
load ('lena512.mat');
pic=uint8(lena512);
hist=imhist(pic);
cdf=cumsum(hist)/ numel(pic);
%% histogram equalization
MEQ=ceil(cdf*255);
picEq=MEQ(pic+1);
picEq=uint8(picEq);
histEq=imhist(picEq);
%% histogram specification
MSP=zeros(1,256);
for i=1:length(cdf)
    [~,ind]=min(abs(cdf(i)-cdfRef));
    MSP(i)=ind-1;
end
picSp=MSP(pic+1);
picSp=uint8(picSp);
histSp=imhist(picSp);

figure(1)
subplot(221)
imshow(pic,[0 255]);
title('original image');
subplot(222)
imhist(pic);
title('original histogram');
subplot(223)
imshow(picEq,[0,255])
title('equalization image');
subplot(224)
imhist(picEq);
title('equalization histogram ');

figure(2)
subplot(321)
imshow(pic,[0 255]);
title('original image');
subplot(322)
imhist(pic);
title('original histogram');

subplot(323)
imshow(imRef,[0 255]);
title('reference image');
subplot(324)
imhist(imRef);
title('reference histogram');

subplot(325)
imshow(picSp,[0,255])
title('specification image');
subplot(326)
imhist(picSp);
title('specification histogram ');


2018-03-01 22:08:52 qq_38352854 阅读数 512

一、什么叫直方图匹配:

    规定处理后的图像的直方图形状,生成特定的直方图。


二、   直方图匹配的意义:

    当图像的灰度大部分集中在图像的暗端,直接进行直方图均衡会导致图像移向较高的一侧,从而产生一幅褪色的图像。而直方图匹配则能保留图像直方图的大体形状,使其不会被映射到较高端,从而使图像褪色。


三、直方图匹配的原理

    考虑归一化后在[0,1]区间内的连续灰度级,令r和z分别表示输入图像与输出图像的灰度级。输入图像灰度级有概率密度函数,输出图像的灰度级具有规定的概率密度函数。其变换为:

                                             

得到的灰度级s,它具有均匀的概率密度函数。现在假设我们定义变量z具有下列特性:

                                            

记住,我们要寻找的时灰度级为z的图像,且具有规定的概率密度函数。由前面两个等式可得:

                                                

我们可以由输入图像得到T(r)(即直方图均衡变换),得到结论:只要找到,就能利用前面的等式得到变换后的灰度级z,其概率密度函数函数(PDF)为规定的。当处理离散变量时,我们能够保证若是正确的直方图概率密度函数(即直方图具有单位面积且其各灰度值均为非负)时,H的反变换存在,且其元素值非零[即中没有容器是空的]。如同在直方图均衡中一样,前面方法的离散实现得到对特定直方图的近似。

四、实例

下面的函数计算一个归一化到单位区域的高斯函数,用其来作为特定指定的直方图。

function p = twomodegauss(m1,sig1,m2,sig2,A1,A2, k)
%计算一个归一化到单位区域的双模态高斯函数,它可被用做一个指定的直方图
c1 = A1 * (1 / ((2 * pi) ^ 0.5) * sig1);
k1 = 2*(sig1^2);
c2 = A2*(1 / ((2 * pi) ^ 0.5) * sig2);
k2 = 2*(sig2^2);
z = linspace(0,1,256);
p = k + c1 * exp(-((z - m1) .^ 2) ./ k1) + c2 * exp(-((z - m2) .^ 2) ./ k2) ;

p = p ./ sum(p(:));



function p = manualhist
%交互式函数从键盘读取输入信息,
%并绘制最终的高斯函数。
%函数input输出包含其参量的文字
%并等待来自用户的输入。
%一组比较好的初始数据为:(-0.85,0.05,0.75,0.05,1,

% 0.07,0.002)


%初始化
repeats = true;
quitnow = 'x';

%如果用户在估计至少一个直方图之前退出,则计算默认直方图
p = twomodegauss(0.15,0.05,0.75,0.05,1,0.07,0.002);

%一直循环直到x输入
while repeats
    s = input('Enter m1,sig1,m2,sig2,A1,A,k OR x to quit:','s');
    if strcmp(s,quitnow)
        break
    end
    
%将输入字符串转换为数值的向量并验证输入的数量 
    
    v = str2num(s);
    if numel(v) ~=7
        disp('Incorrect number of inputs.')
    end
    
    p = twomodegauss(v(1),v(2),v(3),v(4),v(5),v(6),v(7));
    %绘出新的图表,并且规定x坐标
    figure,plot(p)
    xlim([0 255])
end


>> I=imread('MoonPhotos.tif');
g=histeq(I,manualhist);            %进行直方图匹配并生成图像g
Enter m1,sig1,m2,sig2,A1,A,k OR x to quit:0.15 0.05 0.75 0.05 1 0.07 0.002

Enter m1,sig1,m2,sig2,A1,A,k OR x to quit:

以下为manualhist函数生成的图像:



 figure,imhist(g)

以下为图像g的直方图



figure,imhist(I)

以下为原图I的直方图

    

    

     figure,imshow(I)

以下为原图像I:


    

    figure,imshow(g)

以下为直方图匹配后的图像:


在这里,利用直方图匹配改善了图像的视觉效果,相比直方图均衡,使得最低灰度级没有那么高。

当修改双模式高斯函数的参数时,将k=0.002变为0.02,结果如下:

 I=imread('MoonPhotos.tif');
g=histeq(I,manualhist);
Enter m1,sig1,m2,sig2,A1,A,k OR x to quit:0.15 0.05 0.75 0.05 1 0.07 0.02

Enter m1,sig1,m2,sig2,A1,A,k OR x to quit:x

以下为参数改为0.02时的双模高斯函数:


figure,imhist(g)

以下为进行了直方图匹配的图像的直方图:


 figure,imshow(I)

以下为原图像I的图像效果:


figure,imshow(g)

以下为进行了直方图匹配的图片:

注意其中的特例是对比度受限的自适应直方图均衡。这种方法利用直方图匹配的方法来逐个处理图像中的较小区域(称为小片)。然后,使用双线性内插方法将相邻的小片组合起来,从而消除人工引入的边界。特别是均匀灰度区域,可以限制对比度来避免放大噪声。




直方图

阅读数 22

直方图处理

阅读数 166

没有更多推荐了,返回首页