opencv学习笔记第四章 计算图像的直方图

来源:互联网 发布:java 启动参数 编辑:程序博客网 时间:2024/06/11 07:27

直方图:图像像素值的统计表。灰度图像有256个条目(容器)

获取直方图:

void calcHist( const Mat* images, int nimages, const int* channels, InputArray mask,
OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform = true, bool accumulate = false );

获取数组的最大值和最小值:

void cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val,
CvPoint* min_loc=NULL, CvPoint* max_loc=NULL, const CvArr* mask=NULL );
arr
输入数组, 单通道或者设置了 COI 的多通道。
min_val
指向返回的最小值的指针。
max_val
指向返回的最大值的指针。
min_loc
指向返回的最小值的位置指针。
max_loc
指向返回的最大值的位置指针。mask
选择一个子数组的操作掩模。

画线函数:

void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
                     int thickness = 1, int lineType = LINE_8, int shift = 0);

二值化函数:

void cvThreshold( const CvArr* src, CvArr* dst, double threshold,
double max_value, int threshold_type );
src 原始数组(单通道, 8-比特of 32-比特 浮点数).
dst 输出数组,必须与src 的类型一致,或者为8-比特.
threshold 阈值
max_value 使用CV_THRESH_BINARY CV_THRESH_BINARY_INV 的最大值.
threshold_type 阈值类型(见讨论)
函数 cvThreshold对单通道数组应用固定阈值操作。该函数的典型应用是对灰度图像
进行阈值操作得到二值图像。(
cvCmpS 也可以达到此目的) 或者是去掉噪声,例如过滤
很小或很大象素值的图像点。本函数支持的对图像取阈值的方法由 threshold_type 确
定:
threshold_type=CV_THRESH_BINARY:
dst(x,y) = max_value, if src(x,y)>threshold

0, otherwise
threshold_type=CV_THRESH_BINARY_INV:
dst(x,y) = 0, if src(x,y)>threshold
max_value, otherwise
threshold_type=CV_THRESH_TRUNC:
dst(x,y) = threshold, if src(x,y)>threshold
src(x,y), otherwise
threshold_type=CV_THRESH_TOZERO:
dst(x,y) = src(x,y), if (x,y)>threshold
0, otherwise
threshold_type=CV_THRESH_TOZERO_INV:
dst(x,y) = 0, if src(x,y)>threshold
src(x,y), otherwise


#include <stdio.h>#include <iostream>#include "opencv2/opencv.hpp"#include "histogram.h"using namespace std;using namespace cv;int main(){Histogram1D h;Mat image;image = imread("D:/1.jpg", 0);/*MatND histo = h.getHistogram(image);for (int i = 0; i < 256;i++)//cout << "Value" << i << "=" << hist.at<float>(i) << endl;*//*namedWindow("Histogram");imshow("Histogram", h.getHistogramImage(image));*//********************************************************二值化********************************************************/Mat thresholded;threshold(image, thresholded, 60, 255, THRESH_BINARY);namedWindow("thresholded");imshow("thresholded", thresholded);waitKey(0);}
#pragma once#ifndef HISTOGRAM_H#define HISTOGRAM_H#include "opencv2/opencv.hpp"using namespace cv;class Histogram1D{private:int histSize[1];//项的数量float hranges[2];//像素的最小以及最大值const float *ranges[1];//int channels[1];//通道public:Histogram1D()//构造函数{histSize[0] = 256;hranges[0] = 0.0;hranges[1] = 255.0;ranges[0] = hranges;channels[0] = 0;//默认考察0通道}MatND getHistogram(const Mat &image){MatND hist;//hist 是一个一维数组calcHist(&image, 1, channels, Mat(), hist, 1, histSize, ranges);/*CV_EXPORTS void calcHist( const Mat* images, int nimages, const int* channels, InputArray mask,OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform = true, bool accumulate = false );CV_EXPORTS void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask,SparseMat& hist, int dims, const int* histSize, const float** ranges, bool uniform = true, bool accumulate = false);CV_EXPORTS_W void calcHist(InputArrayOfArrays images, const std::vector<int>& channels, InputArray mask, OutputArray hist,const std::vector<int>& histSize, const std::vector<float>& ranges, bool accumulate = false);image。输入的图像的指针,可以是多幅图像,所有的图像必须有同样的深度(CV_8U or CV_32F)。同时一副图像可以有多个channes。        narrays。输入的图像的个数。        channels。用来计算直方图的channes的数组。比如输入是2副图像,第一副图像有0,1,2共三个channel,第二幅图像只有0一个channel,那么输入就一共有4个channes,如果int channels[3] = {3, 2, 0},那么就表示是使用第二副图像的第一个通道和第一副图像的第2和第0个通道来计算直方图。        mask。掩码。如果mask不为空,那么它必须是一个8位(CV_8U)的数组,并且它的大小的和arrays[i]的大小相同,值为1的点将用来计算直方图。        hist。计算出来的直方图        dims。计算出来的直方图的维数。        histSize。在每一维上直方图的个数。简单把直方图看作一个一个的竖条的话,就是每一维上竖条的个数。        ranges。用来进行统计的范围。比如        float rang1[] = {0, 20};        float rang2[] = {30, 40};        const float *rangs[] = {rang1, rang2};那么就是对0,20和30,40范围的值进行统计。uniform。每一个竖条的宽度是否相等*/return hist;}Mat getHistogramImage(const Mat &image) {// Compute histogram firstMatND hist = getHistogram(image);// Get min and max bin valuesdouble maxVal = 0;double minVal = 0;minMaxLoc(hist, &minVal, &maxVal, 0, 0);// Image on which to display histogramMat histImg(histSize[0], histSize[0], CV_8U, Scalar(255));// set highest point at 90% of nbinsint hpt = static_cast<int>(0.9*histSize[0]);// Draw vertical line for each bin for (int h = 0; h < histSize[0]; h++) {float binVal = hist.at<float>(h);int intensity = static_cast<int>(binVal*hpt / maxVal);line(histImg, Point(h, histSize[0]), Point(h, histSize[0] - intensity), Scalar::all(0));/*void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,                     int thickness = 1, int lineType = LINE_8, int shift = 0);*/}return histImg;}};#endif // !HISTOGRAM_H

















原创粉丝点击