EmguCV学习(三)

本文介绍了使用EmguCV进行图像处理的几个关键操作,包括直方图伸展和均衡化提升图像对比度,通过反向投影直方图检测特定图像内容,利用HSV空间进行目标定位,以及应用直方图比较和积分图像进行自动化阈值分割。这些技术在图像分析和目标检测中具有广泛应用。
摘要由CSDN通过智能技术生成

(1)直方图伸展以及直方图均衡化

观察某些图像的释放图可以很容易看到,整个可用的强度值范围并没有被完全利用,特别是图像中比较亮的强度值。这里,通过伸展直方图来生成一个对比度更高的图像。

然后,利用EMgucv的自带函数进行直方图均衡化,值得注意的是,函数库里面的直方图均衡命令是针对灰度值而言的,那么,在处理彩色图像的时候,要么将其转换为灰度图像,要么针对BGR三个通道的直方图分别进行均衡,然后将三幅单通道图像合并得到最后的彩色均衡化图像,也是本节的方案。

//基于查找表的直方图伸展,图像增强
private void button39_Click(object sender, EventArgs e)
{
    if (chapter4Img.IsEmpty)
        return;
    var dhData = getDenseHistogramDataOfImage(chapter4Img);//默认直方图256Bins,像素值方位[0.255]
    RangeF[] minValueAndMaxVlue = new RangeF[3];
    float minValue = 0.01f;//忽略数量少于minValue的箱子,定义数值范围0-1
    if (minValue < 0)
        minValue = 0;
    else if (minValue > 1)
        minValue = 1;
    minValue = chapter4Img.Rows * chapter4Img.Cols * minValue;//计算得到最小箱子
    for(int i=0;i<dhData.Length;i++)
    {
        if(dhData[i]==null)
        {
            minValueAndMaxVlue[i].Max = minValueAndMaxVlue[i].Min = -1f;//及不存在这个通道的数据
            continue;
        }
        minValueAndMaxVlue[i].Min = 0f;
        for (;minValueAndMaxVlue[i].Min < dhData[i].GetBinValues().Length; minValueAndMaxVlue[i].Min+=1)
        {
            if (dhData[i].GetBinValues()[(int)minValueAndMaxVlue[i].Min] > minValue)
                break;
        }
        minValueAndMaxVlue[i].Max = dhData[i].GetBinValues().Length - 1;
        for(;minValueAndMaxVlue[i].Max>=0;minValueAndMaxVlue[i].Max-=1)
        {
            if (dhData[i].GetBinValues()[(int)minValueAndMaxVlue[i].Max] > minValue)
                break;
        }
    }
    var lut = new Image<Bgr, byte>(256, 1);
    List<byte[]> arrayData = new List<byte[]>();
    arrayData.Add(new byte[256]);
    arrayData.Add(new byte[256]);
    arrayData.Add(new byte[256]);
    if (chapter4Img.NumberOfChannels==1)
    {
        for(int i=0;i<256;i++)
        {
            if (i < minValueAndMaxVlue[0].Min)
                arrayData[0][i] = 0;
            else if (i > minValueAndMaxVlue[0].Max)
                arrayData[0][i] = 255;
            else
                arrayData[0][i] = (byte)Math.Round(255.0 * (i - minValueAndMaxVlue[0].Min) / (minValueAndMaxVlue[0].Max - minValueAndMaxVlue[0].Min));
        }
    }
    else//对每个通道进行计算,得到范围
    {
        for(int index=0;index<3;index++)
        {
            arrayData[index] = new byte[256];
            for (int i = 0; i < 256; i++)
            {
                if (i < minValueAndMaxVlue[index].Min)
                    arrayData[index][i] = 0;
                else if (i > minValueAndMaxVlue[0].Max)
                    arrayData[index][i] = 255;
                else
                    arrayData[index][i] = (byte)Math.Round(255.0 * (i - minValueAndMaxVlue[index].Min) / (minValueAndMaxVlue[index].Max - minValueAndMaxVlue[0].Min));
            }
        }
    }
    for(int i=0;i<256;i++)
    {
        for(int j=0;j<3;j++)
        {
            lut.Data[0, i, j] = arrayData[j][i];
        }
    }
 
    Mat resultImg = new Mat();
    if(chapter4Img.NumberOfChannels==1)
    {
        CvInvoke.LUT(chapter4Img, lut.Split()[0].Mat, resultImg);
    }
    else
    {
        CvInvoke.LUT(chapter4Img, lut.Split()[0].Mat, resultImg);
    }
    CvInvoke.NamedWindow("Based on One Channel (Blue)", NamedWindowType.Normal);
    CvInvoke.Imshow("Based on One Channel (Blue)", resultImg);
    //对所有的通道取同样的minValueAndMaxValue范围计算
    arrayData.Add(new byte[256]);//再加一个数组
    int newMinValue = Math.Min((int)Math.Min(minValueAndMaxVlue[0].Min, minValueAndMaxVlue[1].Min), (int)minValueAndMaxVlue[2].Min);
    int newMaxValue= Math.Max((int)Math.Max(minValueAndMaxVlue[0].Max, minValueAndMaxVlue[1].Max), (int)minValueAndMaxVlue[2].Max);
    for(int i=0;i<256;i++)
    {
        if (i < newMinValue)
            arrayData[3][i] = 0;
        else if (i > newMaxValue)
            arrayData[3][i] = 255;
        else
            arrayData[3][i] = (byte)((255.0*(i - newMinValue) / (newMaxValue - newMinValue)));
    }
    var newLut = new Mat(1, 256, DepthType.Cv8U, 1);
    newLut.SetTo(arrayData[3]);
    if(chapter4Img.NumberOfChannels==3)
    {
        CvInvoke.LUT(chapter4Img, newLut, resultImg);
        CvInvoke.NamedWindow("Based on BGR three Channels", NamedWindowType.KeepRatio);
        CvInvoke.Ims
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值