隐私提示:本站使用Microsoft Clarity统计访客信息,关于我将收集你的具体何种信息及如何禁止我收集你的信息请点击这里.

  “电脑有什么用?”,为了回答这个问题笔者尝试探索出更多计算机在生活中能起作用的使用场景。本期作者计划介绍如何使用GNU Octave将文本照片变成便于打印的扫描式图像(即纯白色背景的纯黑色文本图像)。

图像处理效果

  读者或许记得:计算机是用作计算的工具。计算机中的图像也是以数据的形式存储的,首先作者来介绍一下计算机中图像的存储方式。

  一方面,各种颜色均可以红、绿、蓝三种颜色的不同权重混合来得到;另一方面,一幅细节有限的图片总可以用数量有限的彩色小点拼凑出来。人们将由三种原色表示的颜色称为RGB颜色,由有限个小点拼凑出的图片称为点阵图片。

  读者可以将一副仅有一种颜色的图片表示为一个二维矩阵,其中每个数字表示在那一点处颜色的深度。例如下面这四个点组成的简单图像,作者将黑色表示为0,白色表示为1,就能得到这样一个矩阵。

一个简单的图片的矩阵

一个简单的图片

  当读者需要描述一副彩色图像时,只需要根据RGB颜色的原理将三个不同颜色的权重矩阵放在一起,组成一个三维矩阵(可以认为是三个矩阵叠在一起组成的立体矩阵)即可。

  现在作者在自己的计算机上准备了一副名为”img.jpg“的图像文件,并将它放在”/home/xi/Workspace”目录下准备将其中复杂的颜色内容去除,取而代之的是非黑即白的便于印刷的图像。

  假设该图像是由单一颜色的不同深度构成的,那么读者只需要将深度大于某一阈值的颜色设置为黑色,其他部分设置为白色即可完成这一工作。

clc,clear;  

thre=100;   %指定阈值;  

img=imread("/home/xi/Workspace/img.jpg");   %读入图像文件,并用三维矩阵表示;  

%A(A==b)表示A矩阵中满足”A等于b“的部分,这一表达式下面会用到;  
img(img>thre)=255;                          %将大于阈值颜色的部分设置为白色(在计算机中,数值越大表示该颜色越浅淡,颜色深度一般在0-255之间);  
img(img!=255)=0;                            %其他部分设置为黑色;  
imwrite(img,"img_out.jpg")                  %将图像img保存到img_out.jpg中,不指明文件路径时Octave将存放在当前工作目录下;  
imshow(img)                                 %查看图像;  

  看起来接下来读者只需要重复调节阈值到得到满足需要的图像即可。但读者必然会困惑于一个显然存在的问题:一般的图像都是彩色的,要如何将其变为单一颜色呢?

  在某些非专业场合,可以认为灰色图像可以由彩色图像的三个不同颜色矩阵加权求和得到。该变换满足下面的表达式,该表达式近似表示了不同颜色光合成时的功率贡献占比:

彩色到灰度的变换公式

  如此一来,读者可以得到下面这个实用的Octave程序:

clc,clear;

thre=100;

img=imread("/home/xi/Workspace/img.jpg");
img=0.3*img(:,:,1)+0.59*img(:,:,2)+0.11*img(:,:,3);     %
img(img>thre)=255;
img(img!=255)=0;
imwrite(img,"img_out.jpg")
imshow(img)

  上面的代码中,包含了一个作者未曾介绍过的语句,即以百分号结尾的语句。这里img(a,b,c)表示img矩阵中第c层第a行第b列的那个数。这里第三个维度(层)分别为红色、绿色和蓝色。而冒号”:”表示该维度中所有数据。这样一来,本句就完成了上面提到的灰度变换表达式的作用。

  当读者采用二分法时,将可以最多经过8次得到需要的阈值。最终作者在例图中取得的阈值为167。

  需要注意的是,当图像光线明显偏向一方时读者可能需要在光照方向上逐区域使用本文方法。当图像光照或深度变化更加复杂时读者将有必要使用更加现代的图像处理方法,这时读者将需要使用带有图形界面的计算机才能方便操作。

UMRAY

2021.08.29