Qt 5.3 下OpenCV 2.4.11 开发(8)查表法直方图修改图像

接着上节内容,本节添加两个方法 stretch() 方法和 applyLookUp() 方法。第一个方法用于拉伸直方图的准备工作,即排除直方图中没有像素值存在的项;第二个方法用查表法拉伸图像。现在贴出完整代码,Histogram1D.h 代码段如下:

 

#ifndef HISTOGRAM1D_H
#define HISTOGRAM1D_H

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

class Histogram1D
{
public:
    Histogram1D();
    MatND getHistogram(const Mat &source);
    Mat getHistogramImage(const Mat &source);
    Mat stretch(const Mat &source, int minValue);//新方法
    Mat applyLookUp(const Mat &source, const Mat &lookup);//新方法

private:
    int histSize[1];    //直方图项数
    int channels[1];    //通道数量
    float histMinMax[2];    //像素最小值最大值
    const float* ranges[1]; //像素值范围
};

#endif // HISTOGRAM1D_H


Histogram1D.cpp 代码段如下:

 

 

 

 

#include "histogram1d.h"

Histogram1D::Histogram1D()
{
    //1D参数初始化
    histSize[0] = 256;
    histMinMax[0] = 0.0;
    histMinMax[1] = 255.0;
    ranges[0] = histMinMax;
    channels[0] = 0;
}

MatND Histogram1D::getHistogram(const Mat &source)
{
    MatND Hist;
    calcHist(&source, 1, channels, Mat(), Hist, 1, histSize, ranges);
    return Hist;
}

Mat Histogram1D::getHistogramImage(const Mat &source)
{
    MatND hist = getHistogram(source);//计算直方图
    double maxVal = 0;
    double minVal = 0;
    minMaxLoc(hist, &minVal, &maxVal);//获取最大值和最小值
    Mat histImg(histSize[0], histSize[0], CV_8U, Scalar(255));//用于显示直方图图像
    int topPoint = static_cast<int>(0.9*histSize[0]);
    for ( int i = 0; i < histSize[0]; i ++ )
    {
        float binVal = hist.at<float>(i);
        int intensity = static_cast<int>(binVal*topPoint/maxVal);
        line(histImg, Point(i, histSize[0]), Point(i, histSize[0]-intensity),
                                              Scalar::all(0));
    }
    return histImg;
}

Mat Histogram1D::stretch(const Mat &source, int minValue = 0)
{
    MatND hist = getHistogram(source);//计算直方图
    int imin = 0;//寻找直方图左端,即最小值
    for ( ; imin < histSize[0]; imin ++ )
    {
        if ( hist.at<float>(imin) > minValue )
            break;
    }
    int imax = histSize[0] - 1;//寻找直方图右端,即最大值
    for ( ; imax >= 0; imax -- )
    {
        if ( hist.at<float>(imax) > minValue )
            break;
    }

    int dim(256);//创建查找表
    Mat lookup( 1, &dim, CV_8U );//填充查找表
    for ( int i = 0; i < 256; i ++ )
    {
        if ( i < imin ) lookup.at<uchar>(i) = 0;
        else if ( i > imax ) lookup.at<float>(i) = 255;
        else lookup.at<uchar>(i) = static_cast<uchar>(255.0*(i-imin)/(imax-imin) + 0.5);
    }

    Mat result;
    result = applyLookUp( source, lookup );
    return result;
}

Mat Histogram1D::applyLookUp(const Mat &source, const Mat &lookup)
{
    Mat result;
    LUT( source, lookup, result);
    return result;
}

 

 

函数介绍:

LUT() 为 OpenCV 函数,第一个参数为输入图像,第三个参数为输出图像,第二个参数是设定好的1D拉伸直方图向量,第四个参数默认为0,也必须为0,否则会报错。


主函数 main.cpp 代码如下:

 

#include <QCoreApplication>
#include "histogram1d.h"

using namespace cv;
using namespace std;

int main()
{
    Mat src = imread("lena.jpg",0);
    Mat result;
    Histogram1D Hg;
    result = Hg.stretch(src, 50);
    Mat srcHg = Hg.getHistogramImage(src);
    Mat rltHg = Hg.getHistogramImage(result);
    namedWindow("src", 0);
    imshow("src", src);
    namedWindow("srcHg", 0);
    imshow("srcHg", srcHg);
    namedWindow("result", 0);
    imshow("result", result);
    namedWindow("rltHg", 0);
    imshow("rltHg", rltHg);
    waitKey(0);
    return 0;
}

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值