1. 简介

利用OpenCV读取图像,转换为灰度图像,绘制该灰度图像直方图。点击直方图,控制台输出该灰度级像素个数。

2. 原理

(1) 实现原理较为简单,主要利用了OpenCV读取图像,并转换为灰度图像;

    srcImg = imread(" ......");    // “....” 代表图像地址
if (srcImg.empty()) {
return -;
}
imshow(WINDOW_SRCIMG, srcImg);
Mat grayImg;
cvtColor(srcImg, grayImg, CV_BGR2GRAY);
imshow(WINDOW_GRAYIMG, grayImg);

(2) 利用Mat类新建一个固定分辨率的画布,统计处于每一灰度级像素个数,在该画布上绘制灰度直方图。

    int nRows = ,nCols=;
Mat g_dstImg(nRows,nCols, CV_8UC1, Scalar::all()); // 新建画布

同时避免画布中该灰度级太高而超出画布范围,在本程序中采用了等比例缩小的方法。

    int MaxCount = arrayMax(grayLevel,);//寻找在处于某一灰度级中个数最多的像素个数
yscaleRate = double(nRows)/MaxCount ;//y缩放比例
double xscaleRate = nCols / ;//x缩放比例

3. 实施细节

// 灰度直方图.cpp : 定义控制台应用程序的入口点。
// Topic: 绘制灰度图的直方图; 转载请注明出处:Chen_HW (https://www.cnblogs.com/chen-hw/p/11668119.html)
// Env: VS2015 + Debug x64 + OpenCV3.4.1
// Date:2018.11.22 by Chen_HW
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#define WINDOW_SRCIMG "【源图】"
#define WINDOW_GRAYIMG "【灰度图】"
#define WINDOW_HIST "【直方图】"
using namespace std;
using namespace cv;
int arrayMax(int g_arr[], int num);
Mat drawHist(Mat &g_srcImg);
void MouseHandle(int event, int x, int y, int flags, void *param);
Point clickPoint,displayPoint;
bool downFlag = false;
Mat srcImg;
double yscaleRate = ; int main()
{
system("color 3f");
srcImg = imread(" ......"); // “....” 代表图像地址
if (srcImg.empty()) {
return -;
}
imshow(WINDOW_SRCIMG, srcImg);
Mat grayImg;
cvtColor(srcImg, grayImg, CV_BGR2GRAY);
imshow(WINDOW_GRAYIMG, grayImg);
Mat histImg = drawHist(grayImg);
imshow(WINDOW_HIST, histImg);
setMouseCallback(WINDOW_HIST, MouseHandle, (void *)&histImg);//(void *)&srcImg传递给void *param
waitKey();
return ;
}
Mat drawHist(Mat &g_srcImg) {
int nRows = ,nCols=;
Mat g_dstImg(nRows,nCols, CV_8UC1, Scalar::all()); // 新建画布
int grayLevel[] = {};
for (int i = ; i < g_srcImg.rows; ++i) {
for (int j = ; j < g_srcImg.cols; ++j) {
grayLevel[(int)g_srcImg.at<uchar>(i, j)]++;
}
}
int MaxCount = arrayMax(grayLevel,);//寻找在处于某一灰度级中个数最多的像素个数
yscaleRate = double(nRows)/MaxCount ;//y缩放比例
double xscaleRate = nCols / ;//x缩放比例
int yAxis[], xAxis[];
for (int m = ; m < ; m++) {
yAxis[m] = int(grayLevel[m]*yscaleRate);
}
//绘制直方图
for (int n = ; n < ; n++) {
if (n == ) {
xAxis[n + ] = xAxis[n];
}
rectangle(g_dstImg, Point(xAxis[n], yAxis[n]), Point( xAxis[n+], ), Scalar(), -);
//-1表示填充矩形框;正值表示不填充矩形框,更方便观察灰度级像素个数的分布;
//但因为后面需要用到填充的情况,故设置成填充状态 } return g_dstImg;
}
//num:数组元素个数;g_max:返回最大值
int arrayMax(int g_arr[],int num) {
int g_max = ;
int i = ;
while (i < num) {
if ( g_arr[i]>= g_max) {
g_max = g_arr[i];
i++;
}
else {
i++;
}
} return g_max;
}
//event 鼠标事件(如按下鼠标左键、左键抬起、鼠标移动等) x、y 鼠标坐标
void MouseHandle(int event, int x, int y, int flags, void *param) {
Mat &g_srcImg = *(Mat *)(param);
Mat g_tempImg = g_srcImg.clone();
int nCount=;//该列白色像素点个数
int nLevelCount = ;
char text[];//存储文本信息
float g_rate;//该列像素点占总像素点个数的比例
imshow(WINDOW_HIST, g_srcImg);
switch (event) {
case EVENT_LBUTTONDOWN:
clickPoint.x = x;
clickPoint.y = y;
downFlag = true;
break;
default:
break;
}
if (downFlag) {
//displayPoint.x = clickPoint.x;
for (int i = ; i < g_srcImg.rows; ++i) {
if (int(g_srcImg.at<uchar>(i, x)) == ) {
++nCount;
}
}
nLevelCount = (nCount / yscaleRate);
g_rate = float(nCount/ yscaleRate) / (srcImg.rows*srcImg.cols);//此处计算的比例不是精确的
cout << "该灰度级像素点个数: " << nLevelCount << ";占总像素个数的比例: "<<g_rate << endl;
sprintf_s(text, "Rate:%f",g_rate );//该灰度级像素个数占总个数的比例;
putText(g_tempImg, text, clickPoint,FONT_HERSHEY_PLAIN,,Scalar(,,));
imshow(WINDOW_HIST, g_tempImg);
downFlag = false;
}
}

4. 结果

  结果如下图所示,点击右侧每一级灰度直方图,在控制台中会输出该灰度级像素个数,并显示占总像素比例。

【图像处理】利用C++编写函数,绘制灰度图像直方图的更多相关文章

  1. 使用matplotlib中的bar函数绘制柱状图

    使用柱状图显示三日电影的票房信息 要显示的数据为2018年12月7日-9日四场电影的票房信息 四场电影分别为:无名之辈,狗十三,毒液:知名守卫者,憨豆特工3 2018年12月7日四场电影票房分别为:[ ...

  2. C++:利用如下公式,编写函数计算∏的值,直到最后一项的绝对值小于e,主程序接收从键盘输入的e,输出∏的值(保留5位小数)。 ∏/4 = 1-1/3+1/5-1/7...

    利用如下公式,编写函数计算∏的值,直到最后一项的绝对值小于e,主程序接收从键盘输入的e,输出∏的值(保留5位小数). ∏/4 = 1-1/3+1/5-1/7... #include <iostr ...

  3. Python 图像处理 OpenCV (16):图像直方图

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  4. paper 2:图像处理常用的Matlab函数汇总

    一 图像的读写 1 imread imread函数用于读入各种图像文件,如:a=imread('e:\w01.tif') 注:计算机E盘上要有w01相应的.tif文件. 2 imwrite imwri ...

  5. 利用java编写的盲注脚本

    之前在网上见到一个盲注的题目,正好闲来无事,便用java写了个盲注脚本,并记录下过程中的坑 题目源码: <?php header("Content-Type: text/html;ch ...

  6. 品味性能之道<九>:利用Loadrunner编写socket性能测试脚本简述

            一.概述         Loadrunner拥有极为丰富的工具箱,供予我们制造出各种奇妙魔法的能力.其中就有此次要讨论的socket套接字操作.     二.socket概述     ...

  7. 向日葵远程RCE漏洞分析及漏洞利用脚本编写

    0x00 漏洞概述 向日葵是一款免费的,集远程控制电脑.手机.远程桌面连接.远程开机.远程管理.支持内网穿透等功能的一体化远程控制管理软件.如果想要手机远控电脑,或者电脑远控手机可以利用向日葵:如果是 ...

  8. 利用c++编写bp神经网络实现手写数字识别详解

    利用c++编写bp神经网络实现手写数字识别 写在前面 从大一入学开始,本菜菜就一直想学习一下神经网络算法,但由于时间和资源所限,一直未展开比较透彻的学习.大二下人工智能课的修习,给了我一个学习的契机. ...

  9. iOS基本动画/关键帧动画/利用缓动函数实现物理动画效果

    先说下基本动画部分 基本动画部分比较简单, 但能实现的动画效果也很局限 使用方法大致为: #1. 创建原始UI或者画面 #2. 创建CABasicAnimation实例, 并设置keypart/dur ...

随机推荐

  1. http抓包—Content-Type讲解

    1.Content-Type的定义 Content-Type(MediaType),即是Internet Media Type,互联网媒体类型,也叫做MIME类型.在互联网中有成百上千中不同的数据类型 ...

  2. MySQL 基础入门

    MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用 ...

  3. AntDesignPro的权限控制和动态路由

    最近看了AntDesignPro关于权限控制的官方文档以及自己框架里权限控制的实现,总结一下. 先贴一下官网上关于权限控制的图有利于理解 步骤如下: 判断是否有 AccessToken 如果没有则跳转 ...

  4. Web前端基础第一天

    Web标准的构成 结构:结构对于网页元素进行整理和分类,现阶段主要学的是html 表现:表现用于设置元素的板式.颜色.大小等外观样式,主要指的是CSS 行为:行为是指网页模型的定义及交互的编写,现阶段 ...

  5. Linux下安装JDK11

    Linux下安装JDK11 Linux下安装JDK可分为三步: 下载相应版本的压缩包 解压缩并移置相应目录 配置环境变量 验证结果 一.下载相应版本的压缩包 下载压缩包可以通过官网下载,如图: 下载前 ...

  6. 第一行Kotlin系列(一)kotlin按钮点击事件

    按钮findViewBuId <Button android:id="@+id/mButton4" android:layout_width="wrap_conte ...

  7. 利用一个VI写入或读取另一个VI的控件值

    利用一个VI写入或读取另一个VI的控件值(转载自浅浅的小草) 有一个VI,叫未命名1.vi.   还有一个vi,叫未命名2.vi     现在,我在 1.vi里要对2.vi的字符串控件进行写入.  可 ...

  8. [hdu4768]二分

    http://acm.hdu.edu.cn/showproblem.php?pid=4768 题意:n个传单分别发给编号为ai, ai + ci, ai + 2 * ci, .. , ai + k * ...

  9. 网站设计时应考虑哪些因素,以保证网站是对SEO友好

    根据用户的搜索习惯做好栏目的设计 根据用户的习惯做好三大标签的设计 做好首页栏目的展现布局  对于用户来说的重点 展示栏目的合理化 多样化 细节化 代码的静态化 域名 服务器购买稳定 合格 网站内容的 ...

  10. Bash Shell之内建命令和保留字

    转载自:http://blog.chinaunix.net/uid-25880122-id-2941630.html 命令 含义 ! 保留字,逻辑非 : 不做任何事,只做参数展开 . 读取文件并在sh ...