目录
像素
图像数字化是指用数字表示图像,每一幅数字图像都是有M行N列的像素组成的,其中每一个像素都存储一个像素值。计算机通常会把像素值处理为256个灰度级别,这256个灰度级别分别用区间[0,255]中的数值表示,其中,"0"表示纯黑色;"255"表示纯白色。
像素是构成数字图像的基本单位,如下图是一副花朵的图像。
放大图像中蓝色框区域,形成如下的放大图像。
不难发现,放大后的图像是由许多个小方块组成的,通常把一个小方块称作一个像素。因此,一个像素是具有一定面积的一个块,而不是一个点。需要注意的是,像素的形状是不固定的;大多数情况下,像素被认为是方块的,但是有的时候也可能是圆形或其他形状。
1、确定像素位置
图像的水平方向和垂直方向
在Windows系统的画图工具中 打开测试图片,得到如下界面,在这个界面中,我们可以看到在水平方向上的像素个数是590,在垂直方向上的像素个数是600。
根据水平方向和垂直方向上的像素个数,我们绘制如下图的坐标系。
上图中,在水平方向上的像素个数是590个,与其对应的是X轴的取值范围,即0~589;同理,在垂直方向上的像素个数是600个,与其对应的Y轴的取值范围,即0~599。
这样,就可以通过坐标来确定某个像素在图像中的位置。在OpenCV中,某个像素的坐标方式是(y,x),如上图,右下角的像素坐标是(599,589)。
2、获取像素的BGR值
代码
Mat mat = Cv2.ImRead("test.jpg");
Vec3b px =mat.At<Vec3b>(599, 589);
Console.WriteLine("坐标(599, 589)像素的BGR值是"+ px);
Console.ReadKey();
输出
坐标(599, 589)像素的BGR值是Vec3b (35, 155, 131)
人眼能够感知红色、绿色、蓝色这三种不同的颜色,因此把这三种颜色称作三基色。如果将这三种颜色以不同的比例进行混合,人眼就能看见丰富多彩的颜色。
对于计算机,如何对这些颜色进行编码呢?答案是利用色彩空间。也就是说,色彩空间是计算机对颜色进行编码的模型。
以常用的RGB色彩空间为例,在RGB色彩空间中,存在3个通道,即R通道、G通道、B通道。其中,R通道是指红色(Red)通道;G通道是指绿色(Green)通道;B通道是指蓝色(Blue)通道;并且每个色彩通道都在区间[0,255]内取值。
OpenCV对图像的通道顺序进行了转换,即把RGB图像的通道顺序转换为BGR。
分别获取(599, 589)像素的B通道、G通道、R通道的值。
代码
Mat mat = Cv2.ImRead("test.jpg");
Vec3b pixelValue = mat.At<Vec3b>(599, 589);
Console.WriteLine("Pixel value at (599, 589): B = {0}, G = {1}, R = {2}", pixelValue.Item0, pixelValue.Item1, pixelValue.Item2);
Console.ReadKey();
输出
Pixel value at (599, 589): B = 35, G = 155, R = 131
3、修改像素的BGR值
上面我们读取了坐标(599, 589)上像素的BGR值,即(35,155,131)。现在将像素的BGR值由原来的(35,155,131)修改为(255,255,255),代码如下:
Mat mat = Cv2.ImRead("test.jpg");
Vec3b pixelValue = mat.At<Vec3b>(599, 589);
// 修改像素值
pixelValue[0] = 255; // 修改蓝色通道
pixelValue[1] = 255; // 修改绿色通道
pixelValue[2] = 255; // 修改红色通道
mat.At<Vec3b>(599,589) = pixelValue;
Vec3b new_pixelValue = mat.At<Vec3b>(599, 589);
Console.WriteLine("New pixel value at (599, 589): B = {0}, G = {1}, R = {2}", new_pixelValue.Item0, new_pixelValue.Item1, new_pixelValue.Item2);
Console.ReadKey();
输出
New pixel value at (599, 589): B = 255, G = 255, R = 255
对于BGR图像,当每个像素的B、G、R数值相等时,就可以得到灰度图像。其中B=G=R=0为纯黑色;R=G=B=255为纯白色。
实例 修改指定区域的所有像素值为白色
代码
Mat mat = Cv2.ImRead("test.jpg");
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
mat.At<Vec3b>(i, j) = new Vec3b(255, 255, 255);//修改为白色
}
}
Cv2.ImShow("test.jpg", mat);
Cv2.WaitKey();
Cv2.DestroyAllWindows();
效果
左上角区域都为白色