数字图像处理——第六章 彩色图像处理

数字图像处理——第六章 彩色图像处理

文章目录

  • 数字图像处理——第六章 彩色图像处理
    • 1 彩色模型
      • 1.1 RGB彩色模型
      • 1.2 CMY 和CMYK彩色模型
      • 1.3 HSI彩色模型
    • 2 伪彩色图像处理
      • 2.1 灰度分层
      • 2.2 灰度到彩色的变换
    • 3 彩色图像的分割
      • 3.1 RGB中的彩色图像分割
      • 3.2 彩色边缘检测

1 彩色模型

1.1 RGB彩色模型

RGB模型是工业界的一种颜色标准. 是通过对红(Red)、绿(Green)、蓝(Blue)3种颜色亮度的变化以及它们相互之间的叠加来得到各种各样的颜色。RGB彩色空间对应的坐标系统是如图所示的立方体
数字图像处理——第六章 彩色图像处理_第1张图片

其实在绪论中就有说过彩色图像的相关知识,复习亿下。

像素:数字图像由二维的元素组成,每一个元素具有一个特定的位置(x,y)和幅值f(x,y),这些元素就称为像素,它是数字图像的基本单位。

彩色图像:用红、绿、蓝三元组的二维矩阵来表示。三元组的每个数值也是在0-255之间,0表示相应的基色在该像素中没有,而255表示相应的基色在该像素中取得最大值,所以越接近0越黑,越接近255越白。

利用python提取出RGB三通道图像:

数字图像处理——第六章 彩色图像处理_第2张图片

代码如下:

import cv2
import numpy as np 
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
img = cv2.imread('  ')
plt.figure(dpi = 180)

plt.subplot(141)
plt.imshow(img)
plt.title("原图")
plt.subplot(142)
plt.imshow(img[:, :, 0])
plt.title("B")

plt.subplot(143)
plt.imshow(img[:, :, 1])
plt.title("G")

plt.subplot(144)
plt.imshow(img[:, :, 2])
plt.title("R")
plt.tight_layout()
plt.show()

实验结论:首先有个小问题,可以看出原图和真正的原图长得不一样, 这是因为我读取的方式采用的是opencv,而show采用的是matplotlib,这两者接口的模式不一致。opencv 的接口使用BGR模式,而 matplotlib.pyplot 接口使用的是RGB模式。所以上述原图长得不像原图。解决方法,从opencv读取后转成RGB格式 img = img[:, :, [2, 1, 0]]即可,如下所示

数字图像处理——第六章 彩色图像处理_第3张图片

只需要在上述代码中读取img之后,加入 img = img[:, :, [2, 1, 0]]即可。

1.2 CMY 和CMYK彩色模型

CMY是青(Cyan)、洋红或品红(Magenta)和黄(Yellow)三种颜色的简写,是相减混色模式,用这种方法产生的颜色之所以称为相减色,乃是因为它减少了为视觉系统识别颜色所需要的反射光。和RGB的区别在于:RGB是红(Red)、绿(Green)和蓝(Blue)三种颜色的简写,是相加混色模式,每种颜色分量越多,得到的颜色越亮,每种颜色的取值范围为0~255;RGB常用于计算机显示方面
由于彩色墨水和颜料的化学特性,用三种基本色得到的黑色不是纯黑色,因此在印刷术中,常常加一种真正的黑色(black ink),这种模型称为CMYK模型,广泛应用于印刷术。每种颜色分量的取值范围为0~100;CMY常用于纸张彩色打印方面

CMY和RGB其实是互补的颜色类型。
[ C M Y ] = [ 1 1 1 ] − [ R G B ] \left[\begin{array}{c} C \\ M \\ Y \end{array}\right]=\left[\begin{array}{l} 1 \\ 1 \\ 1 \end{array}\right]-\left[\begin{array}{l} R \\ G \\ B \end{array}\right] CMY=111RGB
以上假设所有的颜色全部归一化到了[0,1]之间,C M Y 主要表示颜料的表面所反射的颜色,上式表明涂有青色颜料的表面所反射的光中不包含红色,类似的,纯深红色不反射绿色,纯黄色不反射蓝色。所以CMY其实就是RGB的补色。
因为CMY所组合的颜色不是纯黑,所以为了产生真正的黑色,我们一般在模型里面加入CMYK的k即代表黑色。

1.3 HSI彩色模型

色调H(Hue):与光波的波长有关,它表示人的感官对不同颜色的感受,如红色、绿色、蓝色等,它也可表示一定范围的颜色,如暖色、冷色等。
饱和度S(Saturation):表示颜色的纯度,纯光谱色是完全饱和的,加入白光会稀释饱和度。饱和度越大,颜色看起来就会越鲜艳,反之亦然。
亮度I(Intensity):对应成像亮度和图像灰度,是颜色的明亮程度。

HSI是指一个数字图像的模型,它反映了人的视觉系统感知彩色的方式,以色调、饱和度和亮度三种基本特征量来感知颜色。HSI模型的建立基于两个重要的事实:
第一个,分量与图像的彩色信息无关;
第二个,H和S分量与人感受颜色的方式是紧密相联的。这些特点使得HSI模型非常适合彩色特性检测与分析。

从RGB空间到HSI空间的转换,即分别求出HSI参数
数字图像处理——第六章 彩色图像处理_第4张图片

数字图像处理——第六章 彩色图像处理_第5张图片

代码如下:

def RGB2HSI(rgb_img):
    """
    传入RGB乳香,返回HSI图像
    """
    #保存原始图像的行列数
    row = np.shape(rgb_img)[0]
    col = np.shape(rgb_img)[1]
    #对原始图像进行复制
    hsi_img = rgb_img.copy()
    #对图像进行通道拆分
    B,G,R = cv2.split(rgb_img)
    #把通道归一化到[0,1]
    [B,G,R] = [ i/ 255.0 for i in ([B,G,R])]
    H = np.zeros((row, col))    #定义H通道
    I = (R + G + B) / 3.0       #计算I通道
    S = np.zeros((row,col))      #定义S通道
    for i in range(row):
        den = np.sqrt((R[i]-G[i])**2+(R[i]-B[i])*(G[i]-B[i]))
        thetha = np.arccos(0.5*(R[i]-B[i]+R[i]-G[i])/den)   #计算夹角
        h = np.zeros(col)               #定义临时数组
        #den>0且G>=B的元素h赋值为thetha
        h[B[i]<=G[i]] = thetha[B[i]<=G[i]]
        #den>0且G<=B的元素h赋值为thetha
        h[G[i]<B[i]] = 2*np.pi-thetha[G[i]<B[i]]
        #den<0的元素h赋值为0
        h[den == 0] = 0
        H[i] = h/(2*np.pi)      #弧度化后赋值给H通道
    #计算S通道
    for i in range(row):
        min = []
        #找出每组RGB值的最小值
        for j in range(col):
            arr = [B[i][j],G[i][j],R[i][j]]
            min.append(np.min(arr))
        min = np.array(min)
        #计算S通道
        S[i] = 1 - min*3/(R[i]+B[i]+G[i])
        #I为0的值直接赋值0
        S[i][R[i]+B[i]+G[i] == 0] = 0
    #扩充到255以方便显示,一般H分量在[0,2pi]之间,S和I在[0,1]之间
    hsi_img[:,:,0] = H*255
    hsi_img[:,:,1] = S*255
    hsi_img[:,:,2] = I*255
    return hsi_img

2 伪彩色图像处理

2.1 灰度分层

伪彩色图像处理也叫假彩色图像处理,根据一定的准则对灰度值赋以彩色的处理

灰度级分层通常用于突出感兴趣的特定灰度范围内的亮度。灰度级分层有两大基本方法。

  • 将感兴趣的灰度范围内的值显示为一个值(比如0),而其他范围的值为另外一个值(255)。
  • 将感兴趣的灰度范围内的值显示为一个值(比如0),而其他范围的值不变。

数字图像处理——第六章 彩色图像处理_第6张图片

代码如下:

import cv2
import numpy as np 
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
def grayscale_layer(input_image, spotlight_range_min, spotlight_range_max, means):
    '''
    灰度级分层
    :param input_image: 原图像
    :param spotlight_range_min: 所突出的灰度级范围最小值
    :param spotlight_range_max: 所突出的灰度级范围最大值
    :param means: 分层方式(1,2)
    :return: 灰度级分层后的图像
    '''
    input_image_cp = np.copy(input_image) # 输入图像的副本

    if means == 1: # 方式一(突出指定范围内255,并且变暗非范围内0)
        input_image_cp = np.where((input_image_cp >= spotlight_range_min) & (input_image_cp <= spotlight_range_max), 255, 0)
    elif means == 2: # 方式二(仅突出指定范围内255)
        input_image_cp[np.where((input_image_cp >= spotlight_range_min) & (input_image_cp <= spotlight_range_max))] = 255
    else:
        print("please enter the number of means from 1 to 2")
        return
    
    output_image = input_image_cp
    
    return output_image.astypetype(np.uint8)

img = cv2.imread('  ')
img = img[:, :, [2, 1, 0]]
plt.figure(dpi = 180)

plt.subplot(131)
plt.imshow(img)
plt.title("原图")

plt.subplot(132)
plt.imshow(output_1)
plt.title("output_1")

plt.subplot(133)
plt.imshow(output_2)
plt.title("output_2")

plt.tight_layout()
plt.show()

2.2 灰度到彩色的变换

首先我们需要一张灰度图,读取灰度图的方式有好几种,这里用opencv读取灰度图,然后用matplotlib显示。读取方式为:

img = cv2.imread('  ', 0) # 0代表着以灰度图的方式读取

但是直接使用plt显示图像,它默认使用三通道显示图像。所以你管这绿的叫灰度图?所以在plt.imshow()添加参数,plt.imshow(img, cmap=“gray”),这样就能得到正经的灰度图。

数字图像处理——第六章 彩色图像处理_第7张图片

opencv中自带函数cv2.applyColorMap(img, cv2.COLORMAP_JET)能将灰度图像转化成伪彩色图像,效果如下:

数字图像处理——第六章 彩色图像处理_第8张图片

import cv2
import numpy as np 
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False

img = cv2.imread('C:/Users/yujunliu/Pictures/Saved Pictures/dongman.jpg', 0)
img = img[:, :, [2, 1, 0]]
im_color = cv2.applyColorMap(img, cv2.COLORMAP_JET)

plt.figure(dpi = 100)

plt.subplot(121)
plt.imshow(img, cmap = "gray")
plt.title("灰度图")

plt.subplot(122)
plt.imshow(im_color)
plt.title("伪彩色图像")


plt.tight_layout()
plt.show()

3 彩色图像的分割

彩色空间分割是基于单色图像(灰度图)分割技术在不同颜色通道上实现的。灰度图分割技术常见的有:直方图阀值化、特征聚类、边缘检测、基于区域的、模糊技术、神经网络等。灰度图的分割方法都是基于区域像素的非连续性或相似性。基于非连续性的方法主要是为了检测孤立的点、边缘、线(灰度突然变化的地方)。基于相似性的方法包括阀值、聚类、区域分割合并等。

3.1 RGB中的彩色图像分割

本次目标是将一副图像从rgb颜色空间转换到hsv颜色空间,颜色去除白色背景部分具体就调用了cv2的两个函数,一个是rgb转hsv的函数,另一个是利用cv2.inRange函数设阈值,去除背景部分。

数字图像处理——第六章 彩色图像处理_第9张图片

代码如下:

import cv2
import numpy as np 
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
def color_seperate(image):
        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)   #对目标图像进行色彩空间转换
        #设定蓝色下限
        lower_hsv = np.array([20, 20, 20])          
        #设定蓝色上限
        upper_hsv = np.array([255, 255, 255])        
        mask = cv2.inRange(hsv, lowerb=lower_hsv, upperb=upper_hsv)  
        dst = cv2.bitwise_and(image, image, mask=mask)    
        return dst
        
img = cv2.imread('  ')
out = color_seperate(img)
plt.figure(dpi = 100)

plt.subplot(121)
plt.imshow(img)
plt.title("原图")

plt.subplot(122)
plt.imshow(out)
plt.title("output")


plt.tight_layout()
plt.show()

核心函数在于cv2.inRange,参数有三个
第一个参数:原图

第二个参数:lower_red指的是图像中低于这个lower_red的值,图像值变为0

第三个参数:upper_red指的是图像中高于这个upper_red的值,图像值变为0

而在lower_red~upper_red之间的值变成255

3.2 彩色边缘检测

在图像识别中,需要有边缘鲜明的图像,即图像锐化。图像锐化的目的是为了突出图像的边缘信息,加强图像的轮廓特征,以便于人眼的观察和机器识别。图像边缘检测大幅度地减少了数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性。本次利用Canny算子来实现边缘检测。图像边缘检测必须满足两个条件,一能有效地抑制噪声;二必须尽量精确确定边缘的位置。根据对信噪比与定位乘积进行测度,得到最优化逼近算子,这就是Canny边缘检测算子。

Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是:

  • 最好的检测: 算法能够尽可能多地标识出图像中的实际边缘。

  • 最好的定位: 标识出的边缘要尽可能与实际图像中的实际边缘尽可能接近。

  • 最小的响应:图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘。

这里采用opencv C++版本调用摄像头实现Candy算子:

数字图像处理——第六章 彩色图像处理_第10张图片

代码如下:

#include   
#include
using namespace cv;

int main()
{
     
	VideoCapture capture(0);
	while (1)
	{
     
		Mat frame; 
		Mat dstImage, edge, grayImage;  //参数定义
		capture >> frame; 
		//将原图像转换为灰度图像
		cvtColor(frame, grayImage, CV_BGR2GRAY);
		//先用使用 3x3内核来降噪
		blur(grayImage, edge, Size(3, 3));
		//运行Canny算子
		Canny(edge, edge, 3, 9, 3);
		imshow("读取视频", edge); 
		waitKey(30);
	}
	return 0;
}

你可能感兴趣的:(数字图像处理,opencv,计算机视觉,python,机器学习,图像处理)