OpenCV灰度图的直方图均衡

本文介绍了一个使用ROS和OpenCV进行实时图像处理的项目,包括从摄像头读取图像、转换为灰度图、创建直方图并进行图像均衡化处理。通过分析图像的灰度分布,实现了图像对比度的增强。

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

//
// Created by chrisliu on 2019/9/22.
//

#include "ros/ros.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <algorithm>

using namespace std;
using namespace cv;

int main(int argc, char **argv) {
    VideoCapture capture;
    capture.open(0);//打开相机


    ROS_WARN("*****START");
    ros::init(argc, argv, "histogram");//初始化ROS节点
    ros::NodeHandle n;

    if (!capture.isOpened())
    {
       printf("摄像头没有正常打开,重新插拔工控机上当摄像头\n");
        return 0;
    }
    Mat frame;//当前帧图片


    while (ros::ok()) {
        capture.read(frame);
        if(frame.empty())
       {
            break;
       }

		//读图测试
       // frame = imread("woniu.jpg");
        Mat greyImage;
        //将RGB转化为灰度图
        cvtColor(frame, greyImage, CV_RGB2GRAY);
        imshow("src", greyImage);

        //该数组用于记录灰度像素个数
        int grey[256];
        //将数组归0
        memset(grey, 0, sizeof(grey));
//        cout << sizeof(grey) << endl;
//        for (int i = 255; i >= 0; i--)
//            cout << grey[i] << endl;

        int r = greyImage.rows;//行
        int c = greyImage.cols;//列
        int sum_pixels = r * c;//像素总数
//        cout << r * c << endl;

        for (int w = r; w > 0; w--)
            for (int h = c; h > 0; h--) {
                //grey[灰度值]++,遍历完成后可的每个灰度在图像中的个数,存储于数组grey中
                grey[greyImage.at<uchar>(w, h)]++;
            }

        int maxGrey = *max_element(grey, grey + 255);
        int minGrey = *min_element(grey, grey + 255);

        Mat histogram(256, 256, CV_8U, Scalar(0));

        //r的概率
        float pro_r[256];
        //累计密度
        int projectedGrey[256];
//        memset(accumulateDensep,0, sizeof(accumulateDensep));

//        int pixels = 0;
//        float one = 0;

        for (int i = 0; i < 256; i++) {
            pro_r[i] = (float) grey[i] / sum_pixels;

            float temp = 0;
            for (int j = 0; j < i + 1; j++) {
                temp += pro_r[j];
            }
            //四舍五入,得到灰度值i映射为accumuDense[i]
            //即accumuDense[i]=si=T[i]
            projectedGrey[i] = (int) (255 * temp + 0.5);

//            pixels += grey[i];
//            cout<<frequency[i]<<endl;
//            one += frequency[i];

            line(histogram, Point(i, 255), Point(i, 255 - 8 * maxGrey * pro_r[i]), Scalar(255));
        }
//        cout << pixels << endl;
//        cout << one << endl;
        imshow("histogram", histogram);

        //用于均衡化的数组
        int balanced[256];
        memset(balanced, 0, sizeof(balanced));
        float pro_s[256];
        Mat accumulate_histogram(256, 256, CV_8U, Scalar(0));
        for (int i = 0; i < 256; i++) {
            //获取映射后各个灰度值的像素个数
            //灰度值为i在原图中像素个数为grey[i]
            //i映射为灰度值accumulateDense[i]
            //因此将原味i的像素个数归为accumulateDense[i]下
            //记灰度值为accumulateDense[i]的像素总数为balanced[si]
            balanced[projectedGrey[i]] += grey[i];
//            cout<<i<<":"<<accumulateDense[i]<<endl;
        }
        for (int i = 0; i < 256; i++) {
            //获取均衡化后各灰度值的概率
            pro_s[i] = (float)balanced[i] / sum_pixels;

//            cout<<i<<":"<<balance[i]<<endl;
//            cout<<i<<":"<<pro_s[i]<<endl;

            line(accumulate_histogram, Point(i, 255), Point(i, 255 - 8 * maxGrey * pro_s[i]), Scalar(255));
        }
        imshow("accumulate_histogram", accumulate_histogram);

        for (int w = 0; w < r; w++)
            for (int h = 0; h < c; h++) {
//                cout<<(int)greyImage.at<uchar>(w, h)<<endl;
//                cout<<accumulateDense[(int)greyImage.at<uchar>(w, h)]<<endl;

                //更新均衡化后的每个点的像素
                //原(w,h)处的像素=projectedGrey[原灰度值]=si=映射后的灰度值
                greyImage.at<uchar>(w, h)=projectedGrey[(int)greyImage.at<uchar>(w, h)];
            }

        imshow("balanced",greyImage);
        
        ros::spinOnce();
//		loop_rate.sleep();
        waitKey(5);

    }
    return 0;
}

效果如图
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值