OpenCV学习笔记四-用直方图统计像素

本文介绍了使用OpenCV进行图像处理的技术细节,包括一维直方图的计算与绘制、利用查找表修改图像外观、实现图像颜色减少及直方图均衡化等核心功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OpenCV视觉编程攻略第2版第三章

Chapter4.2计算图像直方图

class Histogram1D {
private:
    int histSize[1];            //直方图中箱子的数量
    float hranges[2];           //值范围
    const float* ranges[1];     //值范围的指针
    int channels[1];            //要检查的通道数量
public:
    Histogram1D(){
        histSize[0] = 256;      //256个箱子    
        hranges[0] = 0.0;       //从0开始(不含)
        hranges[1] = 256.0;     //到256(不含)
        ranges[0] = hranges;    
        channels[0] = 0;
    }

    cv::Mat getHistogram(const cv::Mat &image) {
        cv::Mat hist;
        cv::calcHist(&image,
            1,          //仅作为一个图像的直方图
            channels,   //使用的通道
            cv::Mat(),  //不适用掩码
            hist,       //作为结果的直方图
            1,          //这是一维的直方图
            histSize,   //箱子数量
            ranges      //像素值的范围
        );
        return hist;
    }

    cv::Mat getHistogramImage(const cv::Mat &image, int zoom = 1) {
        //计算直方图
        cv::Mat hist = getHistogram(image);
        //创建图像
        return getImageOfHistogram(hist, zoom);
    }

    static cv::Mat getImageOfHistogram(const cv::Mat &hist, int zoom) {
        //获取箱子值得最大值和最小值
        double maxVal = 0;
        double minVal = 0;
        cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);
        //获取直方图的大小
        int histSize = hist.rows;
        cv::Mat histImg(histSize*zoom, histSize*zoom, CV_8U, cv::Scalar(255));

        //设置最高点为90%(即图像高度)的箱子个数
        int hpt = static_cast<int>(0.9*histSize);
        //为每个箱子画垂直线
        for (auto h = 0; h < histSize; ++h) {
            auto binVal = hist.at<float>(h);
            if (binVal > 0) {
                //用线条画
                int intensity = static_cast<int>(binVal*hpt / maxVal);
                cv::line(histImg, cv::Point(h*zoom, histSize*zoom),
                    cv::Point(h*zoom, (histSize - intensity)*zoom),
                    cv::Scalar(0), zoom);
            }
        }
        return histImg;
    }
};

int main()
{
    cv::Mat image = cv::imread("../pictures/4.png", 0);
    Histogram1D h;
    cv::namedWindow("Image");
    cv::imshow("Image", h.getHistogramImage(image));
    cv::waitKey(0);
    return 0;
}

这里写图片描述

Chapter4.3利用查找表修改图像外观

    static cv::Mat applyLookUp(const cv::Mat &image, const cv::Mat &lookup)
    {
        cv::Mat result;
        //LUT函数在图像上应用查找表,查找表定义了如何把像素值转换成新的值
        cv::LUT(image, lookup, result);
        return result;
    }

反相
这里写图片描述

//利用查找表更加高效实现减色
void colorReduce(cv::Mat &image, int div = 64) {
    cv::Mat lookup(1, 256, CV_8U);
    for (auto i = 0; i < 256; ++i)
        lookup.at<uchar>(i) = i / div*div + div / 2;
    cv::LUT(image, lookup, image);
}

Chapter4.4直方图均衡化

    cv::Mat image = cv::imread("../pictures/4.png", 0);
    cv::Mat result;
    //直方图均衡化处理函数
    cv::equalizeHist(image, result);

均衡化效果,图像的质量有所提升
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值