二十五、二维直方图

news/2024/7/21 7:39:56 标签: opencv, 计算机视觉, 图像处理

项目功能实现:对一张彩色图像进行二维直方图绘制
二维直方图通常在HSV色域空间进行处理
按照之前的博文结构来,这里就不在赘述了

一、头文件

histogram_2d.h

#pragma once

#include<opencv2/opencv.hpp>

using namespace cv;

class HISTOGRAM2D {
public:
	void histogram_2d(Mat& image);
};

#pragma once

二、函数实现

histogram_2d.cpp

Mat hsv, hs_hist;
hsv用于存储转到HSV色域空间的对象信息
hs_hist用于存储直方图数据信息

cvtColor(image, hsv, COLOR_BGR2HSV);
二维直方图通常都转到HSV色域空间中进行处理,其中S:0-255,H:0-180

int hbins = 30, sbins = 32;
H范围0-180,分为30个间隔
S范围0-255,分为32个间隔

bin相当于直方图中的一个柱体

calcHist(&hsv, 1, hs_channels, Mat(), hs_hist, 2, hist_bins, hs_ranges, true, false);
参数一:要处理图片的指针,这里传入的是转到HSV色域空间的hsv对象
参数二:输入图像的个数,这里只处理一张图片,故为1
参数三:需要统计直方图的第几个通道,
参数四:掩模,mask必须是一个8位(CV_8U)的数组并且和images的数组大小相同,这里Mat()表示对图片本身进行处理即可
参数五:直方图计算的结果,通过hs_hist接收
参数六:输出直方图的维度,这里是二维
参数七:直方图中每个dims维度需要分成多少个区间
参数八:统计像素值的区间,0-255
参数九:是否对得到的直方图数组进行归一化处理
参数十:多个图像时,是否累积计算像素值的个数

Mat hist2d_image = Mat::zeros(sbins * scale, hbins * scale, CV_8UC3);
创建画布对象hist2d_image

rectangle(hist2d_image, Point(h * scale, s * scale), Point((h + 1) * scale - 1, (s + 1) * scale - 1), Scalar::all(intensity), -1);
根据参数信息绘制矩形即可,也就是bin,一个个柱体

applyColorMap(hist2d_image,hist2d_image,COLORMAP_JET);
二维的直方图是灰度的,可以转换成自定义彩色图片进行显示
详细可参考博文:九、OpenCV自带colormap

#include"histogram_2d.h"
#include<iostream>
#include<opencv2/opencv.hpp>

void HISTOGRAM2D::histogram_2d(Mat& image) {
	//2D直方图
	Mat hsv, hs_hist;
	cvtColor(image, hsv, COLOR_BGR2HSV);//先转换到HSV色域空间、S:0-255,H:0-180
	int hbins = 30, sbins = 32;//0-180分为30个间隔、0-255分为32个间隔
	int hist_bins[] = { hbins,sbins };
	float h_range[] = { 0,180 };
	float s_range[] = { 0,256 };
	const float* hs_ranges[] = { h_range,s_range };
	int hs_channels[] = { 0,1 };
	calcHist(&hsv, 1, hs_channels, Mat(), hs_hist, 2, hist_bins, hs_ranges, true, false);

	double maxVal = 0;//存储二维直方图中最大值
	minMaxLoc(hs_hist, 0, &maxVal, 0, 0);//归一化
	int scale = 10;
	Mat hist2d_image = Mat::zeros(sbins * scale, hbins * scale, CV_8UC3);//创建画布
	for (int h = 0; h < hbins; h++) {
		for (int s = 0; s < sbins; s++) {
			float binVal = hs_hist.at<float>(h, s);
			int intensity = cvRound(binVal * 255 / maxVal);
			rectangle(hist2d_image, Point(h * scale, s * scale), Point((h + 1) * scale - 1, (s + 1) * scale - 1), Scalar::all(intensity), -1);
		}
	}
	applyColorMap(hist2d_image,hist2d_image,COLORMAP_JET);
	imshow("hist2d_image",hist2d_image);
}

三、主函数

yy_main.cpp

#include <opencv2/opencv.hpp>
#include <iostream>
#include "histogram_2d.h"

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
	Mat src = cv::imread("E:/C++_workspace/beyond.jpg", IMREAD_COLOR);

	if (src.empty()) {
		printf("load image is false...\n");
		return -1;
	}

	namedWindow("yanyu", WINDOW_FREERATIO);
	imshow("yanyu", src);

	HISTOGRAM2D yy;
	yy.histogram_2d(src);

	waitKey(0);
	destroyAllWindows();

	return 0;
}

项目结构如下:
在这里插入图片描述

运行结果如下:
在这里插入图片描述


http://www.niftyadmin.cn/n/5389968.html

相关文章

【JavaScript】使用浏览器提供的 API

文章目录 1. Geolocation API1.1 获取用户当前位置 2. Canvas API2.1 绘制基本图形2.2 绘制图像 3. Web Audio API3.1 播放音频3.2 音频可视化 4. 总结 JavaScript 作为一门强大的脚本语言&#xff0c;可以通过浏览器提供的各种 API&#xff0c;实现丰富的交互和媒体处理功能。…

【力扣hot100】刷题笔记Day12

前言 小涛啊小涛&#xff0c;你不能就这么荒废学习安逸享乐&#xff01;工作找不到啦&#xff01; 104. 二叉树的最大深度 - 力扣&#xff08;LeetCode&#xff09; 递归 class Solution:def maxDepth(self, root: Optional[TreeNode]) -> int:if not root:return 0l_len …

校招面试Java、springboot、mysql基本问题

这里有一些常见的Java、Spring Boot和MySQL面试问题&#xff1a; Java面试问题&#xff1a; Java中的基本数据类型有哪些&#xff1f;什么是Java中的自动装箱和拆箱&#xff1f;什么是面向对象编程&#xff1f;Java中的面向对象编程有哪些特性&#xff1f;Java中的异常处理机…

Devc++ 开发的 Easyx 瓦片地图编辑器之自定义贴图导入模块

接上次开发 Editing While Playing 使用 Easyx 开发的 RPG 地图编辑器 tilemap eaitor-CSDN博客 由于还不能导入自己绘制的贴图&#xff0c;所以还要增加自定义贴图的导入导出模块 这里就单独搓了一个自定义导入导出部分&#xff0c;之后再缝合进瓦片地图编辑器里 #include &…

红队评估四靶场

文章目录 环境搭建1.设置所需网卡2.更改win7设置3.DC设置4.web设置开启docker服务5.kali网段`渗透启动`1.确认对方靶机的IP地址2.端口探测3.web探测`2001端口``2002端口`Tomcat/8.5.19漏洞复现`2003端口`4.docker逃逸5.ssh密钥爆破`域渗透启动`1.提权2.隧道搭建各项配置文件内容…

Linux运维- FTP服务器

FTP服务器的配置与管理 项目场景 学院教职工在日常工作中&#xff0c;经常需要传送一些文件和资料。可以使用移动存储设备转存再复制&#xff0c;或者通过共享文件的方式实现&#xff0c;但是两种方法都不是很简单、方便。相对于这两种方法&#xff0c;使用FTP传送文件和资料…

git 错误:对象文件为空object-file-is-empty

一、现象 error: object file .git/objects/31/65329bb680e30595f242b7c4d8406ca63eeab0 is empty fatal: loose object 3165329bb680e30595f242b7c4d8406ca63eeab0 (stored in .git/objects/31/65329bb680e30595f242b7c4d8406ca63eeab0) is corrupt二、解决方案 1.运行 git …

c++链表的介绍

C中的链表是一种常见的数据结构&#xff0c;用于存储和组织数据。链表由一系列节点组成&#xff0c;每个节点包含一个数据元素和一个指向下一个节点的指针。 链表的优点是可以动态地分配内存并灵活地插入和删除元素。与数组不同&#xff0c;链表的大小可以根据需要增长或缩小。…