福州大学《嵌入式系统综合设计》实验七:图像灰度直方图

news2024/12/23 12:20:26

一、实验目的

直方图是一种统计特征,在图像中广为使用,因为具有计算简便、不受平移、旋转的影响,因此可以作为图像的一种有效的局部/全局特征来表示图像,是图像的重要特征之一。直方图在SIFT算法、HOG算法、直方图均衡等图像特征检测算法中都广为使用。本实验的目的是让大家掌握bmcv_calc_hist、和OpenCV中calcHist函数的使用,可以计算出图像的直方图。

二、实验内容

搭建BMCV环境并成功运行bmcv_calc_hist例程

三、开发环境

开发主机:Ubuntu 22.04 LTS

硬件:算能SE5

四、实验器材

开发主机 + 云平台

五、实验过程与结论

本实验涉及的程序框架与实验4的图4-1一致,仅需根据具体调用的API函数配置相关参数即可,因此接下来重点介绍bmcv_calc_hist API函数的参数及其调用方法。图像灰度直方图因为可以反映图像中灰度的分布情况,常作为图像的一种重要特征。可以通过bmcv提供的bmcv_calc_hist函数实现。

5.1 bmcv_calc_hist函数介绍

bmcv_calc_hist函数形式如下:

bm_status_t bmcv_calc_hist ( bm_handle_t handle, bm_device_mem_t input,
bm_device_mem_t output,
int C, int H, int W,
const int *channels,
int dims,
const int *histSizes,
const float *ranges,
int inputDtype);

其中,handle为bm_handle 句柄; input为已分配好 device memory的输入信息,该device memory 空间存储了输入数据,类型可以是float32 或者uint8,由参数inputDtype决定,其大小为C*H*W*sizeof(Dtype);Output为已分配好 device memory的直方图输出结果信息,该 device memory 空间存储了输出结果,类型为 float, 其大小为 histSizes[0]* histSizes[1]*…… *histSizes[n]*sizeof(float)。

C为输入通道数,H为输入通道高度,W为输入通道宽度,channels为需要计算直方图的 channel 列表,其长度为 dims,每个元素的值必须小于 C; 例如,RGB图像的C=3, 而如果只需要计算R通道图像的直方图,则dims=1;

histSizes:对应每个 channel 统计直方图的份数, ranges:每个通道参与统计的范围,其长度为 2*dims; 例如,对位深为24bit的RGB图像,如果三个通道的颜色值都参加直方图统计,每个通道颜色取值范围从0到255, 因此ranges为[0, 255, 0, 255, 0, 255],如果每个通道的值被分为8个bins,则histSizes为:[8,8,8];

inputDtype:输入数据的类型:0 表示 float,1 表示 uint8。

代码使用范例如下:

int H = 1024;
int W = 1024;
int C = 3;
int dim = 3;
int channels[3] = {0, 1, 2};
int histSizes[] = {15000, 32, 32};
float ranges[] = {0, 1000000, 0, 256, 0, 256};
int totalHists = 1;

for (int i = 0; i < dim; ++i) {
totalHists *= histSizes[i];
}
bm_handle_t handle = nullptr;
bm_status_t ret = bm_dev_request(&handle, 0);
float *inputHost = new float[C * H * W];
float *outputHost = new float[totalHists];

for (int i = 0; i < C; ++i) {
for (int j = 0; j < H * W; ++j)
inputHost[i * H * W + j] = static_cast<float>(rand() % 1000000);
}

//创建图像input,和保持直方图结果的output对象,分配内存;
ret = bmcv_calc_hist(handle,input, output, C, H, W,  channels, dim, histSizes, ranges, 0);
5.2 OpenCV calcHist函数

OpenCV 提供calcHist函数来实现直方图的计算,具体形式如下:

void cv::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 
)
  1. 其中,images为输入的图像的指针;nimages为输入图像个数;channels为需要统计直方图的第几通道。
  2. mask:掩模,mask必须是一个8位(CV_8U)的数组并且和images的数组大小相同;如果其值不为空,则,值为1的点将用来计算直方图。
  3. hist:直方图计算的输出值;dims:输出直方图的维度(由channels指定);histSize:直方图中每个dims维度需要分成多少个区间(如果把直方图看作一个一个竖条的话,就是竖条的个数);ranges:统计像素值的区间;uniform=true:是否对得到的直方图数组进行归一化处理;accumulate= false:在多个图像时,是否累积计算像素值的个数;

调用时,参考代码如下:

//需要计算的图像的通道,灰度图像为3,BGR图像需要指定B,G,R
    const int channels[] - {0 };
    Mat hist; //定义输出Mat类型int dims = 1;
    int dims = 1;//设置直方图维度
    const int histSize[] - { 256 }; //直方图每一个维度划分的柱条的数目
    //每一个维度取值范围
    float pranges[] - { 0, 255 }; //取值区间
    const float* ranges[] - { pranges };
    calcHist(&gray,1, channels, Mat(), hist, dims, histSize,ranges, true, false);
5.3 画直方图

最后输出的结果可以通过OpenCVrectangle函数将点连接起来画出直方图:

int scale = 2;
	int hist_height = 256;
	Mat hist_img = Mat::zeros(hist_height, 256 * scale, CV_8UC3);
	double max_val;
	Mat hist = Mat::zeros(1, 256 , CV_32FC3);;
	for (int i = 0; i < 250; i++)
	{
		hist.at<float>(i) = outputHost[i];
	}
	minMaxLoc(hist, 0, &max_val, 0, 0);
	for (int i = 0; i < 250; i++)
	{
		float bin_val = hist.at<float>(i);
		int intensity = cvRound(bin_val * hist_height / max_val);
        rectangle(hist_img, Point(i * scale, hist_height - 1), Point((i + 1) * scale - 1, 
                  hist_height - intensity), Scalar(255, 255, 255));
	}
	imwrite("bmcv_calc_hist_out.jpg", hist_img);
7.4 执行结果

按照上述步骤,生成可执行文件并上传到算能盒子给可执行文件赋权限并执行:

root@ab162899a93b:/tmp/tmp6l8uq_dw# chmod 777 bmcv_calc_hist

root@ab162899a93b:/tmp/tmp6l8uq_dw# ./bmcv_calc_hist encodeImage.jpg

Open /dev/jpu successfully,device index = 0, jpu fd = 8,vpp fd = 9

执行结果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1251799.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【阿里云】图像识别 智能分类识别 增加网络控制功能点(三)

一、增加网络控制功能 实现需求TCP 心跳机制解决Soket异常断开问题 二、Linux内核提供了通过sysctl命令查看和配置TCP KeepAlive参数的方法。 查看当前系统的TCP KeepAlive参数修改TCP KeepAlive参数 三、C语言实现TCP KeepAlive功能 四、setsockopt用于设置套接字选项的系…

为什么别人能做好CSGO游戏搬砖,而你不能?

CSGO搬砖日常出货更新 做Steam游戏搬砖的门槛很低&#xff0c;以至于这两年不断有小白涌入市场&#xff0c;想要在饰品市场中分一杯羹。这个项目是很简单&#xff0c;但想要站稳脚跟&#xff0c;有稳定收入的第一步就得搞清楚项目逻辑。 首先你得搞清楚&#xff0c;steam搬砖盈…

【MySQL系列】PolarDB入门使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

基于孔雀算法优化概率神经网络PNN的分类预测 - 附代码

基于孔雀算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于孔雀算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于孔雀优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…

巧妙之中见真章:深入解析常用的创建型设计模式

设计模式之创建型设计模式详解 一、设计模式是什么&#xff1f;二、模板方法2.1、代码结构2.2、符合的设计原则2.3、如何扩展代码2.4、小结 三、观察者模式3.1、代码结构3.2、符合的设计原则3.3、如何扩展代码3.4、小结 四、策略模式4.1、代码结构4.2、符合的设计原则4.3、如何…

计算机视觉面试题-01

计算机视觉面试通常涉及广泛的主题&#xff0c;包括图像处理、深度学习、目标检测、特征提取、图像分类等。以下是一些可能在计算机视觉面试中遇到的常见问题&#xff1a; 图像处理和计算机视觉基础 图像是如何表示的&#xff1f; 图像在计算机中可以通过不同的表示方法&…

Leetcode—28.找出字符串中第一个匹配项的下标【简单】

2023每日刷题&#xff08;四十&#xff09; Leetcode—28.找出字符串中第一个匹配项的下标 实现代码 int strStr(char* haystack, char* needle) {int len1 strlen(haystack);int len2 strlen(needle);int idx -1;int i 0;while(i < len1 - len2) {if(strncmp(haystac…

尺度为什么是sigma?

我们先看中值滤波和均值滤波。 以前&#xff0c;我认为是一样的&#xff0c;没有区分过。 他们说&#xff0c;均值滤波有使图像模糊的效果。 中值滤波有使图像去椒盐的效果。为什么不同呢&#xff1f;试了一下&#xff0c;果然不同&#xff0c;然后追踪了一下定义。 12345&…

从程序员到解决方案工程师:一次跨界的职场冒险

在科技行业里&#xff0c;程序员和解决方案工程师是两个非常常见的职业。虽然这两个职业都需要一定的行业理解和问题解决能力&#xff0c;但它们的工作内容和职责却有很大的不同。 那么&#xff0c;如果一名程序员决定转行做一名解决方案工程师&#xff0c;他会经历怎样的体验…

QXDM Filter使用指南

QXDM Filter使用指南 1. QXDM简介2 如何制作和导入Filter2.1 制作Filter2.1.1 制作Windows环境下Filter2.1.2 制作Linux环境下Filter 2.2 Windows环境下导入Filter 3 Filter配置3.1 注册拨号问题3.1.1 LOG Packets(OTA)3.1.2 LOG Packets3.1.3 Event Reports3.1.4 Message Pack…

Java网络爬虫实战

List item 文章目录 ⭐️写在前面的话⭐️&#x1f4cc;What is it?分类网络爬虫按照系统结构和实现技术&#xff0c;大致可以分为以下几种类型&#xff1a;通用网络爬虫&#xff08;General Purpose Web Crawler&#xff09;、聚焦网络爬虫&#xff08;Focused Web Crawler&a…

关于python中的nonlocal关键字

如果在函数的子函数中需要调用外部变量&#xff0c;一般会看见一个nonlocal声明&#xff0c;类似下面这种&#xff1a; def outer_function():x 10def inner_function():nonlocal xx 1print(x)inner_function()outer_function()在这个例子中&#xff0c;inner_function 引用…

AR眼镜双目光波导/主板硬件方案

AR(增强现实)技术的发展离不开光学元件&#xff0c;而在其中&#xff0c;光波导和Micro OLED被视为AR眼镜光学方案的黄金搭档。光学元件在AR行业中扮演着核心角色&#xff0c;其成本高昂且直接影响用户体验的亮度、清晰度和大小等因素。AR眼镜的硬件成本中&#xff0c;光机部分…

Postman如何使用(二):Postman Collection的创建/使用/导出分享等

一、什么是Postman Collection&#xff1f; Postman Collection是可让您将各个请求分组在一起。 您可以将这些请求组织到文件夹中。中文经常将collection翻译成收藏夹。如果再下文中看到这样的翻译不要觉得意外。Postman Collection会使你的工作效率更上一层楼。Postman Colle…

浅谈现代化城市建设中智慧消防的研究与应用

安科瑞 华楠 【摘要】随着城市现代化发展&#xff0c;城市居住密度愈来愈大&#xff0c;城市建筑结构复杂多样化&#xff0c;高层建筑火灾发生率在不断地升高。对现代化城市面临的消防问题展开讨论&#xff0c;针对智慧消防在现代化城市建设中的现状进行了分析&#xff0c;并提…

肾合胶囊 | 修行人追求的“长生不老”,其实就是一个“增阳消阴”的过程!

关于生命的问题&#xff0c;在人们面前有两条路任你选择。 人的生命活动靠精气来维持&#xff0c;善于保养精气者长生&#xff0c;否则就是短寿。 长生或短寿&#xff0c;只能由你自己选择。 其实要想长生并不是很难的事情&#xff0c;长生药就在你自己身上&#xff0c;只不…

YOLO目标检测——背包检测数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;各种背包检测数据集说明&#xff1a;背包检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富标签说明&#xff1a;使用lableimg标注软件标注&#xff0c;标注框质量高&#xff0c;含voc(xml)、coco(json)和yolo(txt)三种格式标签…

SpringBoot 2 系列停止维护,Java8 党何去何从?

SpringBoot 2.x 版本正式停止更新维护&#xff0c;官方将不再提供对 JDK8 版本的支持 SpringBoot Logo 版本的新特性 3.2 版本正式发布&#xff0c;亮点包括&#xff1a; 支持 JDK17、JDK21 版本 对虚拟线程的完整支持 JVM Checkpoint Restore&#xff08;Project CRaC&…

OSG粒子系统与阴影-自定义粒子系统示例<1>(4)

自定义粒子系统示例(一) 自定义粒子系统示例(一)的代码如程序清单11-5所示&#xff1a; /* 自定义粒子系统示例1 */ void particleSystem_11_5(const string &strDataFolder) {osg::ref_ptr<osgViewer::Viewer> viewer new osgViewer::Viewer();osg::ref_ptr<os…

【每日一题】1457. 二叉树中的伪回文路径-2023.11.25

题目&#xff1a; 1457. 二叉树中的伪回文路径 给你一棵二叉树&#xff0c;每个节点的值为 1 到 9 。我们称二叉树中的一条路径是 「伪回文」的&#xff0c;当它满足&#xff1a;路径经过的所有节点值的排列中&#xff0c;存在一个回文序列。 请你返回从根到叶子节点的所有路…