scratch lenet(2): C语言实现图像直方图的计算

news/2024/11/17 2:26:49/

scratch lenet(2): C语言实现图像直方图的计算

1. 目的

用 C 语言实现 uint8 类型图像(单通道)的直方图计算。不涉及直方图均衡化。

2. 什么是图像直方图

2.1 统计得到图像直方图

通常是对于单通道的灰度图而言的。像素范围是 [0, 255], 统计每个像素出现的次数, 存放到一个 256 元素的一维数组 hist 中。换言之, hist 是一个统计结果。

void calculate_histogram(uchar* image, int width, int height, int hist[256])
{memset(hist, 0, 256 * sizeof(int));for (int i = 0; i < height; i++){for (int j = 0; j < width; j++){int idx = i * width + j;uchar v = image[idx];hist[v]++;}}printf("[DEBUG] print histogram:\n");for (int i = 0; i < 256; i++){if (hist[i] > 0){printf("gray value=%d, occurance cnt=%d\n", i, hist[i]);}}
}

2.2 可视化:直方图转为图像表示

所谓可视化直方图, 是说把原本是1维的、256 元素的数组 hist[256], 转为2维图像。 图像宽度是256, 高度是 max(hist[i]).

在计算机视觉中, 白色对应到255,黑色对应到0.

在计算机视觉的C/C++实现中,图像坐标原点是左上角, 而数学中的绘制图像曲线,左下角才是原点。

于是, 需要在获取图像坐标点 P(i, j) 时, 执行坐标变换,得到以左下角为原点时的坐标 P'(inv_i, j)

P' 的取值为 0 或 255: 如果比 hist[j] 要大(坐标点更高),则为255; 否则为0.

typedef struct GrayImage
{int width;int height;uchar* data;
} GrayImage;GrayImage create_gray_image_from_histogram(int hist[256])
{// draw histogram as imageint max_hist = 0;for (int i = 0; i < 256; i++){if (hist[i] > max_hist){max_hist = hist[i];}}int hist_height = max_hist;int hist_width = 256;uchar* image = (uchar*)malloc(hist_height * hist_width);for (int i = 0; i < hist_height; i++){int inv_i = hist_height - 1 - i;for (int j = 0; j < hist_width; j++){int idx = i * hist_width + j;if (inv_i > hist[j]){image[idx] = 255;}else{image[idx] = 0;}}}GrayImage hist_image;hist_image.width = hist_width;hist_image.height = hist_height;hist_image.data = image;return hist_image;
}

2.3 可视化:保存结果图

使用 .pgm 格式。使用 scratch lenet(1): 读写 pgm 图像文件 中实现的 .pgm 图像读写函数。

void write_pgm_image(uchar* image, int width, int height, const char* filename)
{FILE* fout = fopen(filename, "wb");fprintf(fout, "P5\n%d %d\n255\n", width, height);fwrite(image, width * height, 1, fout);fclose(fout);
}

3. 完整代码和结果

#include <stdio.h>
#include <stdlib.h>typedef unsigned char uchar;void write_pgm_image(uchar* image, int width, int height, const char* filename)
{FILE* fout = fopen(filename, "wb");fprintf(fout, "P5\n%d %d\n255\n", width, height);fwrite(image, width * height, 1, fout);fclose(fout);
}void* memset(void* s, int c, size_t n)
{char x = c & 0xff;char* p = (char*)s;for (int i = 0; i < n; i++){p[i] = n;}return s;
}void calculate_histogram(uchar* image, int width, int height, int hist[256])
{memset(hist, 0, 256 * sizeof(int));for (int i = 0; i < height; i++){for (int j = 0; j < width; j++){int idx = i * width + j;uchar v = image[idx];hist[v]++;}}printf("[DEBUG] print histogram:\n");for (int i = 0; i < 256; i++){if (hist[i] > 0){printf("gray value=%d, occurance cnt=%d\n", i, hist[i]);}}
}typedef struct GrayImage
{int width;int height;uchar* data;
} GrayImage;GrayImage create_gray_image_from_histogram(int hist[256])
{// draw histogram as imageint max_hist = 0;for (int i = 0; i < 256; i++){if (hist[i] > max_hist){max_hist = hist[i];}}int hist_height = max_hist;int hist_width = 256;uchar* image = (uchar*)malloc(hist_height * hist_width);for (int i = 0; i < hist_height; i++){int inv_i = hist_height - 1 - i;for (int j = 0; j < hist_width; j++){int idx = i * hist_width + j;if (inv_i > hist[j]){image[idx] = 255;}else{image[idx] = 0;}}}GrayImage hist_image;hist_image.width = hist_width;hist_image.height = hist_height;hist_image.data = image;return hist_image;
}int main()
{uchar image[8 * 8] = {52, 55, 61, 66, 70, 61, 64, 73,63, 59, 55, 90, 109, 85, 69, 72,62, 59, 68, 113, 144, 104, 66, 73,63, 58, 71, 122, 154, 106, 70, 69,67, 61, 68, 104, 126, 88, 68, 70,79, 65, 60, 70, 77, 68, 58, 75,85, 71, 64, 59, 55, 61, 65, 83,87, 79, 69, 68, 65, 76, 78, 94};int width = 8;int height = 8;int hist[256] = { 0 };calculate_histogram(image, width, height, hist);GrayImage hist_image = create_gray_image_from_histogram(hist);write_pgm_image(hist_image.data, hist_image.width, hist_image.height, "histogram.pgm");free(hist_image.data);
}

运行结果

在这里插入图片描述

4. References

  1. 直方图均衡化(HE)

http://www.ppmy.cn/news/438254.html

相关文章

图片清晰化处理

话不多说&#xff0c;直接上干货 放大后对比 进一步放大后对比 其他图片对比 其他图片对比 如需批量处理请私信我。

如何让图片变得更清晰(汇总中)

近日在写论文的时候发现部分图片清晰度较差&#xff0c;为了保持图形的美观&#xff0c;可以使用以下方法&#xff1a; https://bigjpg.com/对图片进行无损放大&#xff0c;增加清晰度

高清图片免费素材网站分享

这3个资源强大的图片素材网站&#xff01;知乎大佬强烈推荐&#xff0c;再也不怕高清配图难找&#xff01; 有效的进行搜索图片就可以大大提高你的工作效率&#xff0c;所以今天跟大家分享3个图片素材网站。可以免费下载高清图片&#xff01; Hippopx 官网地址&#xff1a;h…

人体神经系统分布图高清,神经分布图超清图片

神经元结构图示 。 &#xff08;1&#xff09;由图一可知&#xff0c;图一结构中涉及到3个神经元&#xff0c;含有2个突触&#xff0c;其中A是轴突&#xff08;神经纤维&#xff09;&#xff0c;B是树突&#xff0e;&#xff08;2&#xff09;图二中①是感受器、②是传入神经…

三种方法教你让模糊照片秒变高清图

现在随着数字相机和智能手机的普及&#xff0c;我们拍摄的照片数量越来越多&#xff0c;但是有些照片可能因为环境或技术等原因导致模糊不清&#xff0c;这时候我们就需要使用一些软件或工具来让照片变得清晰&#xff0c;以满足我们的需求。 下面介绍三种常用的照片变清晰的方…

如何提升图片清晰度?有了这4个工具,高糊图片也能变清晰

网上的图片经过多次传播&#xff0c;有的就不是很清晰了&#xff0c;想要提高图片清晰度&#xff0c;可以试试这5个好用的图片修复工具&#xff0c;简单易操作&#xff0c;上传图片就能一键变清晰&#xff01; 1、Bigjpg 一个AI智能图片无损放大工具&#xff0c;使用方便&#…

11个超高清图片素材网站,可直接访问

千图网 https://www.58pic.com/ 昵图网 http://www.nipic.com/ 中国图片库 http://www.tukuchina.cn/ 千库网 http://www.588ku.com/ 汇图网 http://www.huitu.com/ 集图网 http://www.jituwang.com/ 我图网 https://www.ooopic.com/ 爱图网 http://www.aiimg.co…

分享8个免费的超清背景图片下载网站

想用免费的桌面背景图&#xff0c;还是前端开发做页面展示。下面推荐10个超清的免费背景图下载网站&#xff1a; 1.wallhaven.cc wallhaven.cc拥有进1000万张高质量壁纸。无广告&#xff0c;支持名称搜索&#xff0c;像素搜索&#xff0c;整体色调搜索&#xff0c;不支持中文。…