opencv3/C++/Python 绘制直方图&直方图均衡化

opencv3绘制直方图

C++

calcHist参数说明:

void calcHist(
const Mat* images, //源(图像)数组。应具有相同的深度(CV_8U或CV_32F)和大小。每个数组可以有任意数量的通道。
int nimages, //源图像的数量
const int* channels, //用于计算直方图的dims通道列表
InputArray mask, //可选掩码。如果矩阵不为空,它必须是与images[i]大小相同的8位数组。
OutputArray hist, //输出直方图
int dims, //直方图的维度(必须是正数且不能大于CV_MAX_DIMS)
const int* histSize, //每个维度中的直方图大小的数组。
const float** ranges, //每个维度中直方图边界边界的dims数组的数组。
bool uniform = true, //指示直方图是否均匀的标志
bool accumulate = false //累积标志。若设置为true,分配的直方图不会被清除,用于及时更新直方图。
);
示例一
#include<opencv2/opencv.hpp>
using namespace cv;

Mat src;
int histSize = 30;
void histBar(int, void*);
int main()
{

    src = imread("E:/image/panda.jpg");
    if (src.empty())
    {
        printf("can not load image \n");
        return -1;
    }
    namedWindow("image", WINDOW_AUTOSIZE);      
    cvtColor(src, src, COLOR_BGR2GRAY); 
    imshow("image", src);

    namedWindow("histogram", WINDOW_AUTOSIZE);
    createTrackbar("histSize:", "histogram", &histSize,500, histBar);

    waitKey(0);
    return 0;

}

void histBar(int, void*)
{
    MatND hist;
    float range[] = {0, 255};
    const float *ranges = {range};
    //计算直方图
    calcHist(&src, 1, 0, Mat(), hist,1, &histSize, &ranges, true, false);
    //将直方图bin的数值归一化到0-255
    normalize(hist, hist, 0, 255, NORM_MINMAX, -1, Mat());

    //显示直方图
    int binsW = cvRound((double)500/histSize);
    Mat histImg = Mat::zeros(500, 500, CV_8UC3);
    RNG rng(123);
    for (int i = 0; i < histSize; i++)
    {
        Scalar color = Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255));
        rectangle(histImg, Point(i*binsW, 500), Point((i+1)*binsW, 500 - cvRound(hist.at<float>(i) * 500 / 255.0)), color, -1);
    }
    imshow("histogram", histImg);
}

这里写图片描述这里写图片描述

示例二
#include <opencv2/opencv.hpp>
using namespace cv;

Mat src;
int brightness = 40;
int contrast = 40;

// 亮度/对比度回调函数
static void updateBrightnessContrast( int, void* )
{
    int histSize = 64;
    double a, b;
    if( contrast > 0 )
    {
        double delta = 127.*contrast/100;
        a = 255./(255. - delta*2);
        b = a*(brightness - delta);
    }
    else
    {
        double delta = -128.*contrast/100;
        a = (256.-delta*2)/255.;
        b = a*brightness + delta;
    }

    Mat dst, hist;
    src.convertTo(dst, CV_8U, a, b);
    imshow("image", dst);
    //计算直方图
    calcHist(&dst, 1, 0, Mat(), hist, 1, &histSize, 0);
    Mat histImage = Mat::ones(200, 320, CV_8U)*255;
    //归一化
    normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, CV_32F);
    histImage = Scalar::all(255);
    int binW = cvRound((double)histImage.cols/histSize);
    for( int i = 0; i < histSize; i++ )
        rectangle( histImage, Point(i*binW, histImage.rows),
                   Point((i+1)*binW, histImage.rows - cvRound(hist.at<float>(i))), Scalar::all(0), -1, 8, 0 );
    imshow("histogram", histImage);
}


int main( int argc, const char** argv )
{

    // 加载图像
    src = imread( "E:/image/image/daibola.jpg", 0 );
    if(src.empty())
    {
        printf("Can not read the image...\n");
        return -1;
    }
    namedWindow("image", 0);
    namedWindow("histogram", 0);
    createTrackbar("brightness", "image", &brightness, 200, updateBrightnessContrast);
    createTrackbar("contrast", "image", &contrast, 200, updateBrightnessContrast);

    updateBrightnessContrast(0, 0);
    waitKey();
    return 0;
}

这里写图片描述这里写图片描述

直方图均衡化

equalizeHist(src, dst);直方图均衡化(输入必须是8bit的单通道图像)

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
    Mat src,dst;
    src = imread("E:/image/image/daibola.jpg");
    if(src.empty())
    {
        printf("can not load image \n");
        return -1;
    }
    namedWindow("input", CV_WINDOW_AUTOSIZE);
    imshow("input", src);

    cvtColor(src, src, CV_RGB2GRAY);
    equalizeHist(src, dst);

    namedWindow("output", CV_WINDOW_AUTOSIZE);
    imshow("output",dst);
    waitKey();
    return 0;
}

这里写图片描述这里写图片描述

Python

绘制直方图

#!/usr/bin/python
# coding:utf-8
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('daibola.jpg',0)
# 全局阈值
ret1,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
# Otsu's阈值
ret2,th2 = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# 高斯滤波后Otsu阈值
blur = cv2.GaussianBlur(img,(5,5),0)
ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# 绘制所有图像及其直方图
images = [img, 0, th1,
          img, 0, th2,
          blur, 0, th3]
titles = ['Original Noisy Image','Histogram','Global Thresholding (v=127)',
          'Original Noisy Image','Histogram',"Otsu's Thresholding",
          'Gaussian filtered Image','Histogram',"Otsu's Thresholding"]
for i in xrange(3):
    plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray')
    plt.title(titles[i*3]), plt.xticks([]), plt.yticks([])
    plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256)
    plt.title(titles[i*3+1]), plt.xticks([]), plt.yticks([])
    plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray')
    plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])
plt.show()

这里写图片描述

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值