第五篇 直方图
前面举例子时(番外第二篇),有讲到判断巧克力存在时用到了直方图,那么我们现在就开始讲一讲直方图。
直方图这个东西挺简单,其实就是统计一个ROI区域里的灰度分布。ROI Region Of Instrest,中文翻译为感兴趣区域。一般就是我们要处理的目标区域。灰度直方图就是将颜色值按0-255个数量,每一个值进行累加,最后将这个数据生成一张图像,这就是直方图。它的作用主要是方便直观的知道像素数据的分布状态。
先贴上一张原图:
这张图经过直方图后产生的分布数据如下:
看得出来,像素值分布主要还是集中在小于灰度值128的值上。下面我列出统计后的值。
995, 2032, 4084, 2725, 4600, 4582, 3810, 4828, 4294, 3908, 4323, 3935, 4081, 3782, 3448, 3446,
3570, 3356, 3417, 3449, 3498, 3524, 3428, 3418, 3509, 3686, 3708, 3809, 3996, 4002, 4083, 4349,
4405, 4730, 5037, 5201, 5628, 5753, 5936, 5862, 5690, 5956, 5984, 6167, 6193, 6340, 6229, 6235,
6339, 6578, 6584, 6646, 6849, 6950, 6972, 7119, 7187, 7266, 7033, 7380, 7052, 7212, 7329, 7629,
7698, 7633, 7651, 7970, 8226, 8322, 8433, 8448, 8804, 9005, 9313, 9389, 9722, 9861, 10123, 9951,
10040, 10111, 9823, 9895, 10151, 10099, 10089, 9723, 10270, 10408, 10178, 10395, 10229, 10300, 10518, 10136,
9892, 10318, 9899, 10054, 10083, 9975, 10025, 9748, 9916, 9845, 9693, 9483, 9576, 8940, 9083, 8873,
8756, 8580, 8471, 8365, 8253, 8180, 8048, 8016, 7681, 8012, 7568, 7456, 7503, 7339, 7143, 7011,
6985, 7202, 7008, 6853, 6834, 6715, 6539, 6449, 6430, 6254, 6349, 6280, 6217, 6257, 6252, 6009,
5943, 5788, 6022, 5739, 5761, 5579, 5745, 5452, 5532, 5425, 5303, 5305, 5282, 5311, 5283, 5279,
5350, 5302, 5179, 5249, 5177, 5046, 5185, 5260, 5310, 5332, 5346, 5544, 5602, 5432, 5344, 5460,
5151, 5311, 5209, 5281, 5335, 5318, 5369, 5379, 5399, 5397, 5296, 5278, 5399, 5324, 5394, 5418,
5379, 5509, 5477, 5412, 5375, 5274, 5364, 5230, 5327, 5256, 5201, 5195, 5086, 5237, 4927, 4982,
4953, 4948, 4843, 4839, 4940, 4946, 4706, 4726, 4653, 4833, 4855, 4723, 4769, 4767, 5032, 5013,
5040, 5167, 5315, 5160, 4931, 5069, 5039, 4923, 4963, 4614, 4304, 4369, 4337, 4131, 3770, 3804,
3739, 3617, 3395, 3546, 3371, 3384, 3353, 3017, 2787, 3049, 2907, 2714, 3291, 4019, 1817, 878,
蓝色部分明显大一些。
直方图主要应用,一盘是辅助做分割,比如做前景背景分离时,有些情况下会用到。
下面贴上核心代码,代码相对简单,主要是一个统计。这中间一个maxval主要是画图时用来做缩放。如果需要其实完整的代码与工程,可以给我微信留言。谢谢。
for(i = 0;i < src->height ;i++)
{
unsigned char *cptr = src->cptr+i*src->bytePerLine;
for(j = 0;j < src->width;j++)
{
histData[cptr[j]]++;
if(maxVal < histData[cptr[j]])
{
maxVal = histData[cptr[j]];
}
}
}