作者简介
本文来自鲍骞月的投稿,主要讲解图像处理基础,欢迎大家积极留言,提出你的疑问或者建议,与投稿小伙伴交流。
GitHub地址:https://github.com/shentibeitaokongle
干货正文
像素读写(RGB色彩空间)
BufferedImage对象像素读写
获取像素二维数组并转换为一维数组(只针对于int类型的像素数据)
我们首先分析一下像素值的一些属性
像素在Java中存储方式
我们这里讨论的是ARGB/RGB通道类型的像素数据,而且是存储在int型数据中的情况。
在Java中int类型是32位,因为是四个通道,所以每个通道占8位。
但是默认情况是10进制的数据。
像素值取值范围
无符号类型(通常情况下):0-255
有符号类型:-128-127
提取各通道的像素值
通过位运算来将各通道的数据提取出来
Alpha通道
Red通道
Green通道
Blue通道
实现原理
首先,我们的位运算都是针对于二进制数进行的,是16进制数,转成2进制就是,下面来一个具体的例子:
现在有一个整体的像素值,而且它的二进制表示为
我们现在要提取Green通道的值,该通道处于整体数据中的第3个通道,也就是倒数第二个通道,所以我们将整体数据右移8位就可以定位到该通道的数据,(右移后前面要补零)
我们来演示一下:
然后使用位与运算分离数据:
&
得到:
这样就把Green通道中的数据分离出来了,然后转成10进制数就是:
其他通道的提取同理,只是右移的位数不同。
将各通道像素值装载整体数值
原理同样通过位运算实现
像素值统计信息(灰度图)
这里我们想要实现一下图像二值化而且减少重复的一些操作,所以这里只对灰度图进行操作。
统计最值
像素最大值
像素最小值
计算像素最值很简单,就是将一张灰度图中的像素都遍历,然后得到最值,代码如下:
输出:
均值和方差
均值
均值很简单而且上面的程序中已经计算,这里略过…
方差
这里我们计算标准差
首先看一下统计学中标准差的公式:
然后我们用代码实现一下:
num =;
for(introw =; row < height; row++) {
for(intcol =; col < width; col++) {
index = row * width + col;
intpixel = pixels[index];
//因为灰度图的各通道的像素值都一样,这里我们只计算出一个通道的像素值即可
intpr = pixel >>16&0xFF;
num = Math.pow((pr - means),2);
}
}
intlen= width * height;
variance = Math.sqrt(num /len);
System.out.println("variance:"+ variance);
输出:
通过均值的图像二值化
原理很简单,同样先遍历各像素,然后对每个像素值与上面计算出来的均值比较,如果大于均值就把该像素设为最大值,否则就设为最小值,然后将二值化后的各个像素值写回到图片中,就得到了结果。
我们具体实现一下:
/**
* 通过均值实现图像的二值化
*/
for(introw =; row < height; row++) {
for(intcol =; col < width; col++) {
index = row * width + col;
intpixel = pixels[index];
intpr = pixel >>16&0xFF;
//进行二值化操作
if(pr > means) {
pr =255;
}else{
pr =;
}
//将各通道像素装载起来,重新写入
//灰度图alpha通道值都为255
pixels[index] = (255
}
}
setRGB(image,,, width, height, pixels);
输出:
效果还是很明显的。
通过方差确定图片信息
方差可以反映一群数据中每个数据与总体均数的差异程度,试想一张空白图片或者一张纯色图片,它的方差肯定为0或者接近于0,所以方差就是图片的一个很重要的信息。
领取专属 10元无门槛券
私享最新 技术干货