当前位置: 首页 > article >正文

opencv图像直方图

【欢迎关注编码小哥,学习更多实用的编程方法和技巧】

1、基本直方图计算

// 灰度图直方图
cv::Mat calculateGrayscaleHistogram(const cv::Mat& image) {
    cv::Mat histogram;
    int histSize = 256;  // 灰度级别
    float range[] = {0, 256};
    const float* histRange = {range};
    
    cv::calcHist(
        &image,      // 输入图像
        1,           // 图像数量
        0,           // 通道索引
        cv::Mat(),   // 掩膜
        histogram,   // 输出直方图
        1,           // 直方图维度
        &histSize,   // 直方图大小
        &histRange   // 像素值范围
    );
    
    return histogram;
}

// 彩色图直方图
std::vector<cv::Mat> calculateColorHistogram(const cv::Mat& image) {
    std::vector<cv::Mat> histograms(3);
    int histSize = 256;
    float range[] = {0, 256};
    const float* histRange = {range};
    
    // 分离通道
    std::vector<cv::Mat> channels;
    cv::split(image, channels);
    
    // 计算每个通道直方图
    for (int i = 0; i < 3; i++) {
        cv::calcHist(
            &channels[i],  // 输入通道
            1,             // 图像数量
            0,             // 通道索引
            cv::Mat(),     // 掩膜
            histograms[i], // 输出直方图
            1,             // 直方图维度
            &histSize,     // 直方图大小
            &histRange     // 像素值范围
        );
    }
    
    return histograms;
}

 2、直方图可视化

class HistogramVisualizer {
public:
    // 绘制直方图
    static cv::Mat drawHistogram(const cv::Mat& histogram, int height = 400) {
        // 归一化直方图
        cv::Mat normalizedHist;
        cv::normalize(histogram, normalizedHist, 0, height, cv::NORM_MINMAX);
        
        // 创建绘图画布
        int width = 512;
        cv::Mat histImage(height, width, CV_8UC3, cv::Scalar(255, 255, 255));
        
        // 绘制直方图
        int binWidth = cvRound((double)width / histogram.rows);
        for (int i = 1; i < histogram.rows; i++) {
            cv::line(
                histImage, 
                cv::Point(binWidth * (i - 1), height - cvRound(normalizedHist.at<float>(i - 1))),
                cv::Point(binWidth * i, height - cvRound(normalizedHist.at<float>(i))),
                cv::Scalar(0, 0, 0), 
                2
            );
        }
        
        return histImage;
    }
    
    // 绘制彩色直方图
    static cv::Mat drawColorHistogram(const std::vector<cv::Mat>& histograms) {
        int height = 400;
        int width = 512;
        cv::Mat histImage(height, width, CV_8UC3, cv::Scalar(255, 255, 255));
        
        std::vector<cv::Scalar> colors = {
            cv::Scalar(255, 0, 0),   // 蓝色
            cv::Scalar(0, 255, 0),   // 绿色
            cv::Scalar(0, 0, 255)    // 红色
        };
        
        // 归一化直方图
        std::vector<cv::Mat> normalizedHists(3);
        for (int i = 0; i < 3; i++) {
            cv::normalize(histograms[i], normalizedHists[i], 0, height, cv::NORM_MINMAX);
        }
        
        // 绘制直方图
        int binWidth = cvRound((double)width / histograms[0].rows);
        for (int i = 1; i < histograms[0].rows; i++) {
            for (int channel = 0; channel < 3; channel++) {
                cv::line(
                    histImage, 
                    cv::Point(binWidth * (i - 1), height - cvRound(normalizedHists[channel].at<float>(i - 1))),
                    cv::Point(binWidth * i, height - cvRound(normalizedHists[channel].at<float>(i))),
                    colors[channel], 
                    2
                );
            }
        }
        
        return histImage;
    }
};

3、直方图均衡化 

class HistogramEqualizer {
public:
    // 灰度图均衡化
    static cv::Mat equalizeGrayscaleImage(const cv::Mat& image) {
        cv::Mat equalizedImage;
        cv::equalizeHist(image, equalizedImage);
        return equalizedImage;
    }
    
    // 彩色图均衡化
    static cv::Mat equalizeColorImage(const cv::Mat& image) {
        // 转换到YUV空间
        cv::Mat yuvImage;
        cv::cvtColor(image, yuvImage, cv::COLOR_BGR2YUV);
        
        // 分离通道
        std::vector<cv::Mat> channels;
        cv::split(yuvImage, channels);
        
        // 仅均衡化亮度通道
        cv::equalizeHist(channels[0], channels[0]);
        
        // 合并通道
        cv::merge(channels, yuvImage);
        
        // 转换回BGR
        cv::Mat equalizedImage;
        cv::cvtColor(yuvImage, equalizedImage, cv::COLOR_YUV2BGR);
        
        return equalizedImage;
    }
    
    // 自适应直方图均衡化(CLAHE)
    static cv::Mat adaptiveHistogramEqualization(const cv::Mat& image, double clipLimit = 2.0) {
        cv::Mat yuvImage;
        cv::cvtColor(image, yuvImage, cv::COLOR_BGR2YUV);
        
        std::vector<cv::Mat> channels;
        cv::split(yuvImage, channels);
        
        // 创建CLAHE对象
        cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE(clipLimit, cv::Size(8, 8));
        clahe->apply(channels[0], channels[0]);
        
        cv::merge(channels, yuvImage);
        
        cv::Mat equalizedImage;
        cv::cvtColor(yuvImage, equalizedImage, cv::COLOR_YUV2BGR);
        
        return equalizedImage;
    }
};

 4、直方图比较

class HistogramComparator {
public:
    // 直方图比较方法
    enum CompareMethod {
        CORRELATION = cv::HISTCMP_CORREL,
        CHI_SQUARE = cv::HISTCMP_CHISQR,
        INTERSECTION = cv::HISTCMP_INTERSECT,
        BHATTACHARYYA = cv::HISTCMP_BHATTACHARYYA
    };
    
    // 比较两个直方图
    static double compareHistograms(
        const cv::Mat& hist1, 
        const cv::Mat& hist2, 
        CompareMethod method = CORRELATION
    ) {
        return cv::compareHist(hist1 , hist2, method);
    }
};

// 使用示例
cv::Mat image1 = cv::imread("image1.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat image2 = cv::imread("image2.jpg", cv::IMREAD_GRAYSCALE);

cv::Mat hist1 = calculateGrayscaleHistogram(image1);
cv::Mat hist2 = calculateGrayscaleHistogram(image2);

double similarity = HistogramComparator::compareHistograms(hist1, hist2, HistogramComparator::CORRELATION);
std::cout << "Histogram similarity: " << similarity << std::endl; ```cpp
// 重新合并通道
cv::Mat processedImage;
cv::merge(channels, processedImage);
return processedImage;
}

// 使用示例
cv::Mat inputImage = cv::imread("input.jpg");
cv::Mat outputImage = processImageChannels(inputImage);

// 显示结果
cv::imshow("Processed Image", outputImage);
cv::waitKey(0);
cv::destroyAllWindows();
``` ```cpp
// 重新合并通道
cv::Mat processedImage;
cv::merge(channels, processedImage);
return processedImage;
}

// 使用示例
cv::Mat inputImage = cv::imread("input.jpg");
cv::Mat outputImage = processImageChannels(inputImage);

// 显示结果
cv::imshow("Processed Image", outputImage);
cv::waitKey(0);
cv::destroyAllWindows();
}


http://www.kler.cn/a/463749.html

相关文章:

  • 第2章:SQL基础
  • unity学习5:创建一个自己的3D项目
  • mysql 忘记root密码 无密码登录系统 配置文件怎么改?
  • 【开源项目】数字孪生立交~东湖高新区互通式立交数字孪生可视化项目——开源工程及源码
  • 数字PWM直流调速系统设计(论文+源码)
  • 物联网控制期末复习
  • 运动健康小程序SpringBoot+论文源码调试讲解
  • RabbitMQ-TTL机制
  • 缓存菜品的业务代码
  • 政策助力数字金融,CES Asia 2025展望科技新未来
  • AI 自动化编程对编程教育的影响
  • 每天五分钟机器学习:凸集
  • uni-app tab 双击事件监听
  • 前端小白学习之路-Vben探索 配置详情 - 2/50
  • 二、github基础
  • 【疑难杂症】 HarmonyOS NEXT中Axios库的响应拦截器无法拦截424状态码怎么办?
  • scala图书管理系统 【dao】软件包
  • A-Tune性能优化工具介绍
  • Python 语言实现 IP 地址转换
  • Linux Kernel Programming4
  • linux-24 文件管理(二)文件编辑,字符集,nano,文件删除,rm
  • 【Web安全】文件写入漏洞 ASP 网页病毒模拟(文件写入漏洞+FilesystemObject)
  • STM32单片机芯片与内部52 I2C 数据手册 寄存器
  • Prometheus 采集 JVM 数据
  • 从0到机器视觉工程师(二):封装调用静态库和动态库
  • 重启ubuntu服务器,如何让springboot服务自动运行