颜色直方图


首先,先介绍一些Hist的基本使用。

Ref:【OpenCV】数字图像灰度直方图

官方文档:https://docs.opencv.org/trunk/d8/dbc/tutorial_histogram_calculation.html

不错博文:利用OpenCV的calcHist绘制灰度直方图、H-S直方图、BGR直方图和自定义直方图的源码及说明

From: compare histograms of grayscale images in opencv

#include <opencv2/opencv.hpp>

void show_histogram(std::string const& name, cv::Mat1b const& image)
{
// Set histogram bins count
int bins = ;
int histSize[] = {bins};
// Set ranges for histogram bins
float lranges[] = {, };
const float* ranges[] = {lranges};
// create matrix for histogram
cv::Mat hist;
int channels[] = {}; // create matrix for histogram visualization
int const hist_height = ;
cv::Mat3b hist_image = cv::Mat3b::zeros(hist_height, bins); cv::calcHist(&image, , channels, cv::Mat(), hist, , histSize, ranges, true, false); double max_val=;
minMaxLoc(hist, , &max_val); // visualize each bin
for(int b = ; b < bins; b++) {
float const binVal = hist.at<float>(b);
int const height = cvRound(binVal*hist_height/max_val);
cv::line
( hist_image
, cv::Point(b, hist_height-height), cv::Point(b, hist_height)
, cv::Scalar::all()
);
}
cv::imshow(name, hist_image);
} int main (int argc, const char* argv[])
{
// here you can use cv::IMREAD_GRAYSCALE to load grayscale image, see image2
cv::Mat3b const image1 = cv::imread("C:\\workspace\\horse.png", cv::IMREAD_COLOR);
cv::Mat1b image1_gray;
cv::cvtColor(image1, image1_gray, cv::COLOR_BGR2GRAY);
cv::imshow("image1", image1_gray);
show_histogram("image1 hist", image1_gray); cv::Mat1b const image2 = cv::imread("C:\\workspace\\bunny.jpg", cv::IMREAD_GRAYSCALE);
cv::imshow("image2", image2);
show_histogram("image2 hist", image2); cv::waitKey();
return ;
}

Histogram equalization


参考:笑得很甜

偏差、增益参数

线性混合算子

非线性算子

覆盖算子


直方图均衡化

直方图的观看规则就是“左黑右白”,左边代表暗部,右边代表亮部,而中间则代表中间调。 纵向上的高度代表像素密集程度,越高,代表的就是分布在这个亮度上的像素很多。

如何看懂照片的直方图?

对比度

对比度在直方图上的体现就是高光和阴影部分都有像素。
它可以很少,但是必须有,否则照片看起来就很灰了。正常照片变为低对比度后的直方图对比:
                     

  当然,也有看起来不错的低对比度图片,但它的直方图不会像上图那样极端,一般都是没有纯黑,但高光都比较足:
  

均衡化

(a) vs (e)  对比度有所加强。

However,可能放大暗区域的噪声。

它的基本思想是对图像中像素个数多的灰度级进行展宽,而对图像中像素个数少的灰度进行压缩,从而扩展像原取值的动态范围,提高了对比度和灰度色调的变化,使图像更加清晰。

http://blog.csdn.net/xiaowei_cqu/article/details/7606607
从分布图上的理解就是希望原始图像中y轴的值在新的分布中尽可能的展开。
变换过程是利用累积分布函数对原始分布进行映射,生成新的均匀拉伸的分布。
因此,对应每个点的操作是寻找原始分布中y值在均匀分布中的位置,如下图是理想的单纯高斯分布映射的示意图:

int main()
{
IplImage * image= cvLoadImage("baboon.jpg");
//显示原图及直方图
myShowHist("Source",image); IplImage* eqlimage=cvCreateImage(cvGetSize(image),image->depth,);
//分别均衡化每个信道
IplImage* redImage=cvCreateImage(cvGetSize(image),image->depth,);
IplImage* greenImage=cvCreateImage(cvGetSize(image),image->depth,);
IplImage* blueImage=cvCreateImage(cvGetSize(image),image->depth,);
cvSplit(image,blueImage,greenImage,redImage,NULL); cvEqualizeHist(redImage,redImage);
cvEqualizeHist(greenImage,greenImage);
cvEqualizeHist(blueImage,blueImage);
//均衡化后的图像
cvMerge(blueImage,greenImage,redImage,NULL,eqlimage);
myShowHist("Equalized",eqlimage);
}

cvEqualizeHist

此函数只能处理单通道的灰色图像,对于彩色图像,我们可以把每个信道分别均衡化,再Merge为彩色图像。

算法演示:

自定义均衡化

(直方图匹配 or 直方图规定化)

//将图像与特定函数分布histv[]匹配
void myHistMatch(IplImage *img,double histv[])
{
int bins = ;
int sizes[] = {bins};
CvHistogram *hist = cvCreateHist(,sizes,CV_HIST_ARRAY);
cvCalcHist(&img,hist);
cvNormalizeHist(hist,);
double val_1 = 0.0;
double val_2 = 0.0;
uchar T[] = {};
double S[] = {};
double G[] = {};
for (int index = ; index<; ++index)
{
val_1 += cvQueryHistValue_1D(hist,index);
val_2 += histv[index];
G[index] = val_2;
S[index] = val_1;
} double min_val = 0.0;
int PG = ;
for ( int i = ; i<; ++i)
{
min_val = 1.0;
for(int j = ;j<; ++j)
{
if( (G[j] - S[i]) < min_val && (G[j] - S[i]) >= )
{
min_val = (G[j] - S[i]);
PG = j;
} }
T[i] = (uchar)PG;
} uchar *p = NULL;
for (int x = ; x<img->height;++x)
{
p = (uchar*)(img->imageData + img->widthStep*x);
for (int y = ; y<img->width;++y)
{
p[y] = T[p[y]];
}
}
} // 生成高斯分布
void GenerateGaussModel(double model[])
{
double m1,m2,sigma1,sigma2,A1,A2,K;
m1 = 0.15;
m2 = 0.75;
sigma1 = 0.05;
sigma2 = 0.05;
A1 = ;
A2 = 0.07;
K = 0.002; double c1 = A1*(1.0/(sqrt(*CV_PI))*sigma1);
double k1 = *sigma1*sigma1;
double c2 = A2*(1.0/(sqrt(*CV_PI))*sigma2);
double k2 = *sigma2*sigma2;
double p = 0.0,val= 0.0,z = 0.0;
for (int zt = ;zt < ;++zt)
{
val = K + c1*exp(-(z-m1)*(z-m1)/k1) + c2*exp(-(z-m2)*(z-m2)/k2);
model[zt] = val;
p = p +val;
z = z + 1.0/;
}
for (int i = ;i<; ++i)
{
model[i] = model[i]/p;
}
}

cvCalcHist

将图像规定化为高斯分布函数。

算法演示:

计算变换函数 根据 规定的直方图 得来。但非严格单调,所以需要:

    (a:s值) --> (b:z值)    

发现:S0G(Z3)竟然一致,正好匹配。

对比直方图

通过直方图匹配,可以使图像的相似度变高,但也仅仅是从颜色的角度。

int main()
{
IplImage * image= cvLoadImage("myhand1.jpg");
IplImage * image2= cvLoadImage("myhand2.jpg");
int hist_size=;
float range[] = {,};
float* ranges[]={range}; IplImage* gray_plane = cvCreateImage(cvGetSize(image),,);
cvCvtColor(image,gray_plane,CV_BGR2GRAY);
CvHistogram* gray_hist = cvCreateHist(,&hist_size,CV_HIST_ARRAY,ranges,);
cvCalcHist(&gray_plane,gray_hist,,); IplImage* gray_plane2 = cvCreateImage(cvGetSize(image2),,);
cvCvtColor(image2,gray_plane2,CV_BGR2GRAY);
CvHistogram* gray_hist2 = cvCreateHist(,&hist_size,CV_HIST_ARRAY,ranges,);
cvCalcHist(&gray_plane2,gray_hist2,,); //相关:CV_COMP_CORREL
//卡方:CV_COMP_CHISQR
//直方图相交:CV_COMP_INTERSECT
//Bhattacharyya距离:CV_COMP_BHATTACHARYYA
double com=cvCompareHist(gray_hist,gray_hist2,CV_COMP_BHATTACHARYYA); cout<<com<<endl;
}

cvCompareHist

cvCompareHist的结果为【0,1】的浮点数,越小表示两幅图匹配度越高,0.0时两幅图精确匹配。  

提供的对比方法有四种:

     

局部增强 (涉及到统计,大有可为)

分辨亮区域与暗区域的不同,同时只增强暗区域。

[OpenCV] Image Processing - Grayscale Transform的更多相关文章

  1. [OpenCV] Image Processing - Grayscale Transform & Histogram

    颜色直方图 首先,先介绍一些Hist的基本使用. Ref:[OpenCV]数字图像灰度直方图 官方文档:https://docs.opencv.org/trunk/d8/dbc/tutorial_hi ...

  2. [OpenCV] Image Processing - Fuzzy Set

    使用模糊技术进行 (灰度变换Grayscale Transform) 和 (空间滤波Spatial Filtering) 模糊集合为处理不严密信息提供了一种形式. 首先,需要将输入量折算为隶属度,这个 ...

  3. 使用OpenMP加快OpenCV图像处理性能 | speed up opencv image processing with openmp

    本文首发于个人博客https://kezunlin.me/post/7a6ba82e/,欢迎阅读! speed up opencv image processing with openmp Serie ...

  4. 使用OpenCL提升OpenCV图像处理性能 | speed up opencv image processing with OpenCL

    本文首发于个人博客https://kezunlin.me/post/59afd8b3/,欢迎阅读最新内容! speed up opencv image processing with OpenCL G ...

  5. [OpenCV] Image Processing - Spatial Filtering

    "利用给定像素周围的像素的值决定此像素的最终的输出值“ 教学效果: 策略: 1. 拉普拉斯,突出小细节: . 梯度,突出边缘: . 平滑过的梯度图像用于掩蔽: . 灰度变换,增加灰度动态范围 ...

  6. [OpenCV] Image Processing - Image Elementary Knowledge

    "没有坚实的理论基础,实践只会浅尝于表面." 这是两本打基础的书,没系统学过的话,怎么好意思说自己会CV. 该领域,兴军亮 这个名字屡次出现,看来是计算机视觉领域国内的年轻才俊,向 ...

  7. [Python] python vs cplusplus

    一些学习过程中的总结的两种语言的小对比,帮助理解OO programming. Continue... 字典 序列 --> 字典 Python: def get_counts(sequence) ...

  8. 本人AI知识体系导航 - AI menu

    Relevant Readable Links Name Interesting topic Comment Edwin Chen 非参贝叶斯   徐亦达老板 Dirichlet Process 学习 ...

  9. OpenCV 编程简单介绍(矩阵/图像/视频的基本读写操作)

    PS. 因为csdn博客文章长度有限制,本文有部分内容被截掉了.在OpenCV中文站点的wiki上有可读性更好.而且是完整的版本号,欢迎浏览. OpenCV Wiki :<OpenCV 编程简单 ...

随机推荐

  1. FreeCodeCamp 中级算法(个人向)

    freecodecamp 中级算法地址戳这里 Sum All Numbers in a Range 我们会传递给你一个包含两个数字的数组.返回这两个数字和它们之间所有数字的和. function su ...

  2. shell切割日志脚本

    #!/bin/bash set -e source /etc/bashrc cd `dirname $` linenum=`wc -l userinfolist.txt | awk '{print $ ...

  3. 解决ScrollView嵌套ListView,ListView填充容器后,界面自动滚动回顶部的问题

    1.scrollView.scrollTo(0,0),有时可以,有时不行: 2.listView.post(new Runnable() {                               ...

  4. 17数据表&E-R模型&概念数据模型上-选学天轰穿大话数据库视频教程

    大纲:解剖“数据表”,戏说E-R模型,概念数据模型(E-R 到 CDM),使用PowerDesigner创建概念模型,生成逻辑数据模型 土豆超清地址: 腾讯超清地址: 百度云盘下载地址:上传ing,稍 ...

  5. html5使用FileReader上传图片

    客户端代码是网上找的,修改为.net代码. <html><head>    <meta charset="utf-8">    <titl ...

  6. 【资源集合】94个iOS开发资源推荐,帮你加速应用开发

    资源总结类文章总是开发者们所喜欢的,网上已经有各种weekly.头条以及期刊类资源总结,今天这篇来自于开发者Viswateja Reddy的总结.原文对各个项目的介绍非常简单,为了更便于阅读,编辑在原 ...

  7. 《STL系列》之vector原理及实现

    最近忙得蛋疼,但还是想写点属于自己的东西.也不知道写点啥,最后决定试着自己实现STL中常用的几个集合,一来加深自己对STL的理解,二来看看自己是否有这个能力实现.实现目标就是:1能和STL兼容:2最大 ...

  8. 如何在使用MAMP环境下安装MySQLdb

    我的电脑上没有安装XAMPP,而是安装了MAMP PRO,其实两者都差不多,都是PHP+MySQL+Apache的集成环境,只是MAMP的GUI界面更华丽一些,但是也更复杂一些. 好了不说这些,说说问 ...

  9. git的一些相关知识

    1.配置多个git远程仓库的ssh-Key切换(转自) 目前的git仓库如github都是通过使用SSH与客户端连接,如果只是固定使用单个git仓库的单个用户 (first),生成生成密钥对后,将公钥 ...

  10. 计算空间直线与平面的交点 (C#)

    public class NGlbVec3d    {// 三维点        public double x, y, z;        public NGlbVec3d()        {   ...