2019-05-04 11:03:38 zaishuiyifangxym 阅读数 755

目录

1 图像灰度化原理

2 图像颜色空间转换

3 OpenCV图像灰度化处理

3.1 最大值灰度处理

3.2 平均灰度处理

3.3 加权平均灰度处理

参考资料


1 图像灰度化原理

在图像处理算法中,往往需要把彩色图像转换为灰度图像。图像灰度化是将一幅彩色图像转换为灰度化图像的过程。彩色图像通常包括R、G、B三个分量,分别显示出红绿蓝等各种颜色,灰度化就是使彩色图像的R、G、B三个分量相等的过程。灰度图像中每个像素仅具有一种样本颜色,其灰度是位于黑色与白色之间的多级色彩深度,灰度值大的像素点比较亮,反之比较暗,像素值最大为255(表示白色),像素值最小为0(表示黑色)。假设某点的颜色由RGB(R,G,B)组成,常见灰度处理算法有:

       算法名称                           算法公式 

 最大值灰度处理

              gray=\max (R,G,B)

   浮点灰度处理

     gray=0.3R+0.59G+0.11B

   整数灰度处理

   gray=(30R+59G+11B)/100

   移位灰度处理

  gray=(28R+151G+77B)>>8

   平均灰度处理

                 gray=(R,G,B)/3

加权平均灰度处理

 gray=0.299R+0.587G+0.144B

其中,常见的灰度处理方法是将RGB三个分量求和再取平均值,但更为准确的方法是设置不同的权重,将RGB分量按不同的比例进行灰度划分。比如人类的眼睛感官蓝色的敏感度最低,敏感最高的是绿色,因此将RGB按照0.299、0.587、0.144比例加权平均能得到较合理的灰度图像

                                                                             gray=0.299R+0.587G+0.144B


 

2 图像颜色空间转换

在日常生活中,我们看到的大多数彩色图像都是RGB类型,但是在图像处理过程中,常常需要用到灰度图像、二值图像、HSV、HSI等颜色,OpenCV提供了 cvtColor() 函数实现这些功能。

OpenCV中 cvtColor() 函数形式如下所示:

dst = cv2.cvtColor(src, code[, dst[, dstCn]])

src 表示输入图像,需要进行颜色空间变换的原图像;

dst 表示输出图像,其大小和深度与src一致;

code 表示转换的代码或标识;

dstCn 表示目标图像通道数,其值为0时,则有src和code决定。

该函数的作用是将一个图像从一个颜色空间转换到另一个颜色空间,其中,RGB是指Red、Green和Blue,一幅图像由这三个通道(channel)构成;Gray表示只有灰度值一个通道;HSV包含Hue(色调)、Saturation(饱和度)和Value(亮度)三个通道。在OpenCV中,常见的颜色空间转换标识包括CV_BGR2BGRA、CV_RGB2GRAY、CV_GRAY2RGB、CV_BGR2HSV、CV_BGR2XYZ、CV_BGR2HLS等。

下面是调用 cvtColor() 函数将图像颜色空间转换(BGR、RGB、GRAY、HSV、YCrCb、HLS、XYZ、LAB 和 YUV)

代码如下所示:

#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取原始图像
img_BGR = cv2.imread('zxp.jpg')

#BGR转换为RGB
img_RGB = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2RGB)

#灰度化处理
img_GRAY = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2GRAY)

#BGR转HSV
img_HSV = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2HSV)

#BGR转YCrCb
img_YCrCb = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2YCrCb)

#BGR转HLS
img_HLS = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2HLS)

#BGR转XYZ
img_XYZ = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2XYZ)

#BGR转LAB
img_LAB = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2LAB)

#BGR转YUV
img_YUV = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2YUV)

#调用matplotlib显示处理结果
titles = ['BGR', 'RGB', 'GRAY', 'HSV', 'YCrCb', 'HLS', 'XYZ', 'LAB', 'YUV']
images = [img_BGR, img_RGB, img_GRAY, img_HSV, img_YCrCb,
          img_HLS, img_XYZ, img_LAB, img_YUV]
for i in range(9):
   plt.subplot(3, 3, i+1), plt.imshow(images[i], 'gray')
   plt.title(titles[i])
   plt.xticks([]),plt.yticks([])
plt.show()

cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:


 

3 OpenCV图像灰度化处理

下面主要介绍最大值灰度处理平均灰度处理加权平均灰度处理 算法。

3.1 最大值灰度处理

该方法的灰度值等于彩色图像R、G、B三个分量中的最大值,公式如下:

                                                                               gray=\max (R,G,B)

 

代码如下所示:

#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取原始图像
img = cv2.imread('zxp.jpg')

#获取图像高度和宽度
height = img.shape[0]
width = img.shape[1]

#创建一幅图像
grayimg = np.zeros((height, width, 3), np.uint8)

#图像最大值灰度处理
for i in range(height):
    for j in range(width):
        #获取图像R G B最大值
        gray = max(img[i,j][0], img[i,j][1], img[i,j][2])
        #灰度图像素赋值 gray=max(R,G,B)
        grayimg[i,j] = np.uint8(gray)

#显示图像
cv2.imshow("src", img)
cv2.imshow("gray", grayimg)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:(处理效果的灰度偏亮

 

 

3.2 平均灰度处理

该方法的灰度值等于彩色图像R、G、B三个分量灰度值的求和平均值,其计算公式如下所示:

                                                                                    gray=(R,G,B)/3

 

代码如下所示:

#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取原始图像
img = cv2.imread('zxp.jpg')

#获取图像高度和宽度
height = img.shape[0]
width = img.shape[1]

#创建一幅图像
grayimg = np.zeros((height, width, 3), np.uint8)
# print (grayimg)

#图像平均灰度处理方法
for i in range(height):
    for j in range(width):
        #灰度值为RGB三个分量的平均值
        gray = (int(img[i,j][0]) + int(img[i,j][1]) + int(img[i,j][2]))  /  3
        grayimg[i,j] = np.uint8(gray)

#显示图像
cv2.imshow("src", img)
cv2.imshow("gray", grayimg)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:

 

 

3.3 加权平均灰度处理

该方法根据色彩重要性,将三个分量以不同的权值进行加权平均。常见的灰度处理方法是将RGB三个分量求和再取平均值,但更为准确的方法是设置不同的权重,将RGB分量按不同的比例进行灰度划分。比如人类的眼睛感官蓝色的敏感度最低,敏感最高的是绿色,因此将RGB按照0.299、0.587、0.144 比例加权平均能得到较合理的灰度图像:

                                                                       gray=0.299R+0.587G+0.144B

 

代码如下所示:

#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取原始图像
img = cv2.imread('zxp.jpg')

#获取图像高度和宽度
height = img.shape[0]
width = img.shape[1]

#创建一幅图像
grayimg = np.zeros((height, width, 3), np.uint8)
# print grayimg

#图像加权平均灰度处理方法
for i in range(height):
    for j in range(width):
        #灰度加权平均法
        gray = 0.30 * img[i,j][0] + 0.59 * img[i,j][1] + 0.11 * img[i,j][2]
        grayimg[i,j] = np.uint8(gray)

#显示图像
cv2.imshow("src", img)
cv2.imshow("gray", grayimg)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:

 


 

参考资料

[1] https://blog.csdn.net/Eastmount/article/details/88785768

[2] Python+OpenCV图像处理

2019-07-12 09:39:34 mzl_18353516147 阅读数 31

目标

• 学习如何对图像颜色空间转换,比如从 BGR 到灰度图,或者从 BGR 到 HSV 等。

• 创建一个程序用来从一幅图像中获取某个特定颜色的物体。

• 掌握函数cv2.cvtColor()、cv2.inRange() 等的常用法。


1.颜色空间转换

在 OpenCV 中有 150 中颜色空间转换的方法。但经常用到的也就两种BGR↔Gray 和 BGR↔HSV。 我们用到的函数是cv2.cvtColor(input_image,flag),其中input_image是待转换的图像, flag是转换类型。 对于BGR↔Gray的转换,我们使用的flag就是cv2.COLOR_BGR2GRAY。 同样对于BGR↔HSV的转换,我们用的flag就是cv2.COLOR_BGR2HSV。 你可以下的命令得到所有可用的 flag。

import cv2
for i in dir(cv2):
    if i.startswith('COLOR_'):
        print(i)

或者简写为:
import cv2
flags = [i for i in dir(cv2) if i.startswith('COLOR_')]
print(flags)

其中,startswith()函数是Python的字符串函数,用于检测字符串是否以指定字符串开头。如果是则返回True,否则返回False.

用法是:str.startswith(str2),

str 待检测的字符串  
str2 检测str2字符串是否是str字符串的开头

在 OpenCV 的 HSV 格式中,H(色彩/色度)的取值范围是 [0,179], S(饱和度)的取值范围 [0,255],V(亮度)的取值范围 [0,255]。但是不同的软件使用的值可能不同。所以当你拿 OpenCV 的 HSV 值与其他软件的 HSV 值对比时,一定要记得归一化.

2.物体跟踪

在知道了将一幅图像从 BGR 转换到 HSV 之后,我们可以利用这一点来提取带有某个特定色的物体。因为在 HSV 颜色空间比在 BGR 颜色空间中更容易示一个特定色。下面我们的程序提取的是一个蓝色的物体。步骤如下:

• 从视频中获取每一帧图像

• 将图像转换到 HSV 空间

• 设置 HSV 阈值的蓝色范围。

• 获取蓝色物体

当然我们可以做其他任何我们想做的事,比如在蓝色物体周围画一个圈。下就是我们的代码:

# 获取视频中的蓝色物体
import numpy as np
import cv2
 
cap = cv2.VideoCapture(0)
 
while(True):
    # 获取每一帧
    ret, frame = cap.read()
 
    # 转换为HSV
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
 
    # 设定蓝色的阈值
    lower_blue = np.array([110,50,50])
    upper_blue = np.array([130,255,255])
 
    # 依据阈值构建掩摸
    mask = cv2.inRange(hsv, lower_blue,upper_blue)
 
    # 对原图像和掩摸进行位运算
    res = cv2.bitwise_and(frame, frame,mask=mask)
 
    # 显示图像
    cv2.imshow('frame',frame)
    cv2.imshow('mask', mask)
    cv2.imshow('res', res)
    k = cv2.waitKey(3)&0xFF
    if k == 27:
        break
cap.release()
cv2.destroyAllWindows()

程序执行后,按ESC键退出程序并释放摄像头,注意:这只是一个最简单的物体跟踪方法,显示的图像中可能会有噪声, 实际做项目时候,需要进行适当的去噪。当你学习了轮廓之后,我们可以找到物体的重心,根据重心来跟踪物体,那时候我们仅仅在摄像头前挥挥手就可以画出一个圆形,甚至会有一些其它更有趣的事情。

3.怎样找到要跟踪对象的HSV值

我们会在stackoverflow.com上经常遇到这个问题。其实真的很简单,函数 cv2.cvtColor() 也可以用到。但是现在你传入的参数是(你想要的)BGR 值而不是一副图。例如我们要找到绿色的 HSV 值,我们只需要在终端输入以下命令:

import cv2 
import numpy as np
# green=np.uint8([0,255,0]) # 这种方式会报错
green=np.uint8([[[0,255,0]]]) # 的三层括号应分别对应于cvArray cvMat IplImage
hsv_green=cv2.cvtColor(green,cv2.COLOR_BGR2HSV) 
print(hsv_green) 

现在你可以分别用 [H-100,100,100] 和 [H+100,255,255] 做上下阈值。除了这个方法之外你可以使用任何其他图像编软件,(例如 GIMP )或者在线性转换软件找到相应的 HSV 值,但是最后别忘了节 HSV 的范围。

 

思考:想一想。如何同时提取多个不同颜色的物体,比如同时提取红蓝绿三个不同颜色的物体。

 

 

 

2015-04-01 12:39:05 Trent1985 阅读数 2576

图像处理中,为了便于分析各种图像特征,出现了多种颜色空间,这些颜色空间直接的关系如何,我们在这里做个总结:

1,RGB颜色空间

Win8Metro(C)数字图像处理--4.1RGB颜色空间 - CSharp - C

2,XYZ颜色空间

Win8Metro(C)数字图像处理--4.2XYZ颜色空间 - CSharp - C

Win8Metro(C)数字图像处理--4.2XYZ颜色空间 - CSharp - C

3,YUV颜色空间

4,HIS颜色空间

Win8Metro(C)数字图像处理--4.4HIS颜色空间 - CSharp - C

Win8Metro(C)数字图像处理--4.4HIS颜色空间 - CSharp - C

Win8Metro(C)数字图像处理--4.4HIS颜色空间 - CSharp - C

5,YIQ颜色空间

Win8Metro(C)数字图像处理--4.5YIQ颜色空间 - CSharp - C

6,HSV颜色空间

Win8Metro(C)数字图像处理--4.5HSV颜色空间 - CSharp - C

Win8Metro(C)数字图像处理--4.5HSV颜色空间 - CSharp - C

Win8Metro(C)数字图像处理--4.5HSV颜色空间 - CSharp - C

7,CMYK颜色空间

Win8Metro(C)数字图像处理--4.7CMYK颜色空间 - CSharp - C

Win8Metro(C)数字图像处理--4.7CMYK颜色空间 - CSharp - C

以上是各个颜色空间与RGB颜色空间的对应关系,大家可以自行编程实现,相信有了公式,代码应该很简单了!



2017-06-30 11:57:32 qq_38311041 阅读数 743

第六章 彩色图像处理

RGB图像

  • RGB图像形成
    由三幅单色亮度图像组成。 fR, fG和fB分别表示三幅RGB分量图像

    rgb_image = cat(3, fR, fG, fB)

  • 提取分量图像

>> f = imread('D:\picture\素\sky.jpg');
>> fR = f(:, :, 1);
>> fG = f(:, :, 2);
>> fB = f(:, :, 3);
>>> subplot(121), imshow(f)
>> subplot(122), imshow(fR)
>> subplot(121), imshow(fG)
>> subplot(122), imshow(fB)

sky1
sky2

  • 自定义函数rgbcube
    rgbcube(vx, vy, vz)该函数生成一个从点(vx, vy, vz)观察的RGB立方体。
>> rgbcube(10,10,4); 
>> axis on;
>> title('RGB立方体');
![RGB立方体](http://img.blog.csdn.net/20170627103731064?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzgzMTEwNDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

索引图像

索引图像有两个分量:一个整数数据矩阵X和一个彩色映射矩阵map。
索引图像

>> f = imread('D:\picture\素材\tower.jpg');
>> [X, map] = rgb2ind(f, 16, 'nodither');
>> subplot(221), imshow(f), title('原图')
>> subplot(222), imshow(X), title('X')
>> subplot(223), imshow(map), title('map')
>> subplot(224), imshow(X, map), title('索引图')
![这里写图片描述](http://img.blog.csdn.net/20170629092523503?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzgzMTEwNDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 2. 处理RGB和索引图像的函数 ![函数](http://img.blog.csdn.net/20170627111722482?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzgzMTEwNDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

dither主要与函数rgb2ind联合使用,以减少图像中的颜色数。

>> f = imread('D:\picture\MATLAB\flower.png');
>> [X1, map1] = rgb2ind(f, 8, 'nodither');
>> [X2, map2] = rgb2ind(f, 8, 'dither');
>> g = rgb2gray(f);
>> g1 = dither(g);
>> subplot(221); imshow(X1, map1), title('rgb2ind(f, 8, ''nodither'')');
>> subplot(221); imshow(f), title('原图');
>> subplot(222); imshow(X1, map1), title('rgb2ind未抖动');
>> subplot(223); imshow(X2, map2), title('rgb2ind抖动');
>> subplot(224); imshow(g), title('rgb2gray');
>> figure, imshow(g1), title('dither');
![这里写图片描述](http://img.blog.csdn.net/20170627161849850?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzgzMTEwNDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) ![这里写图片描述](http://img.blog.csdn.net/20170627161916860?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzgzMTEwNDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

彩色空间转换

NTSC彩色空间

NTSC彩色制式用于模拟电视。这种形式主要优点是:灰度信息和彩色数据是分离的。所以同一信号既可以用于彩色电视又可以用于黑白电视。
这里写图片描述
图像数据的三个分量: Y(亮度),I(色调),Q(饱和度)

  • yiq_image = rgb2ntsc(rgb_image)将RGB图像转化为NTSC图像
>> f = imread('D:\picture\MATLAB\flower.png');
>> g = rgb2ntsc(f);
>> imshow(g)  

flower

>> f = imread('D:\picture\MATLAB\flower.png');
>> g = rgb2ntsc(f);
>> g1 = g(:, :, 1);
>> g2 = g(:, :, 2);
>> g3 = g(:, :, 3);
>> subplot(131), imshow(g1), title('亮度图像');
>> subplot(132), imshow(g2), title('色调图像');
>> subplot(133), imshow(g3), title('饱和度图像');            

flower

YCbCr彩色空间

YCbCr彩色空间广泛用于数字视频。亮度信息用Y表示,彩色信息存储为两个色差分量Cb和Cr。Cb是蓝色分量和参考值的差,Cr是红色分量和参考值的差。
这里写图片描述

  • ycbcr_image = rgb2ycbcr(rgb_image)函数实现RGB图像转换为YCbCr图像。
>> f = imread('D:\picture\MATLAB\flower.png');
>> g = rgb2ycbcr(f);
>> imshow(g)

这里写图片描述

HSV彩色空间

HSV(色调Hue,饱和度Saturation,数值Value)是人们从颜色轮或调色版中挑选颜色时所用的几种彩色系统之一。这种系统比RGB系统更接近人们经验和描述彩色感觉时所用的方式。HSV彩色系统基于圆柱坐标系
这里写图片描述
轴表示灰度深浅,色调表示为围绕彩色六边形的角度,饱和度由距V轴的距离来度量。

  • hsv_image = rgb2hsv(rgb_image)函数实现RGB转换为HSV。
>> f = imread('D:\picture\MATLAB\flower.png');
>> g = rgb2hsv(f);
>> imshow(g)

这里写图片描述

CMY和CMYK彩色空间

青色(Cyan),深红色(Magenta),黄色(Yellow)是光的二次色。纯青色涂覆的表面反射的光中不包含红色,深红色不反射绿色,纯黄色不反射蓝色。从RGB转换为CMY近似于以下公式:
这里写图片描述
理论上等量的青色,深红色和黄色混合后会产生黑色。但实际中会产生模糊不清的黑色。所以为生成纯黑色,又加入了黑色,便出现了CMYK彩色模型。

  • cmy_image = imcomplement(rgb_image)函数可近似的把RGB模型转换为CMY模型。
>> f = imread('D:\picture\MATLAB\flower.png');
>> g = imcomplement(f);
>> imshow(g)

这里写图片描述

HSI彩色空间

HSI(色彩hue,饱和度saturation, 强度intensity)

  • 自定义函数hsi = rgb2hsi(rgb)实现RGB转换为HSI。
>> imshow(rgb2hsi(f));

这里写图片描述

彩色图像处理基础

彩色图像处理细分为三个主要领域:

  • 彩色变换(彩色映射)
  • 各个彩色平面的空间处理
  • 彩色向量处理
    在RGB系统中,每个彩色点都可以解释为一个从原点延伸到RGB坐标系中该点的向量
    这里写图片描述
    这里写图片描述

彩色变换

自定义函数ice(交互颜色编辑)
g = ice(‘Property Name’, ‘Property Value’, …)
这里写图片描述

g = ice('image', f);
![这里写图片描述](http://img.blog.csdn.net/20170629130101146?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzgzMTEwNDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
  • 负片
    这里写图片描述

  • 对单色图像进行对比度增强
    这里写图片描述
    这里写图片描述

  • 对彩色图像进行对比度增强
    这里写图片描述
    这里写图片描述
  • 伪彩色映射

    主要应用于人眼可视化,因为人眼可以分辨上百万种颜色,但只能分辨为数不多的灰度级。
    这里写图片描述
    这里写图片描述
    这里写图片描述

  • 彩色平衡

    独立地映射一幅图像思维彩色分量,一个重要应用是照片增强。
    这里写图片描述
    这里写图片描述
    减少了深红色对图像颜色的影响,校正平衡。

  • 基于直方图的映射

    直方图均衡是一种灰度级映射处理,它试图产生具有均匀灰度直方图的单色图像。

>> f = imread('D:\picture\MATLAB\冈萨雷斯数字图像处理MATLAB版图片\dipum_images_ch06\laboratory.tif');
>> g = ice('image', f, 'space', 'HSI'); 
>> subplot(121), imshow(f), title('原图');
>> subplot(122), imshow(g), title('映射后的结果');

这里写图片描述

彩色图像的空间滤波

彩色图像平滑

使用一个线性空间滤波器来平滑一幅RGB图像fc的步骤:

  • 抽取三幅分量图像
  • 分别对每幅分量图像滤波
  • 重建滤波后的RGB图像

函数fc_filtered = imfilter(fc, w, ‘replicate’)可以实现以上步骤

>> f = imread('D:\picture\MATLAB\flower.png');
>> fR = f(:, :, 1);
>> fR = f(:, :, 2);
>> fB = f(:, :, 3); 
>> subplot(141), imshow(f), title('原图');
>> subplot(142), imshow(fR), title('红分量');
>> subplot(143), imshow(fG), title('绿分量');
>> subplot(144), imshow(fB), title('蓝分量');   

这里写图片描述

>> h = rgb2hsi(f);
>> H = h(:, :, 1);
>> S = h(:, :, 2);
>> I = h(:, :, 3);
>> subplot(131), imshow(H), title('色调分量');
>> subplot(132), imshow(S), title('饱和度分量');
>> subplot(133), imshow(I), title('亮度分量');       

这里写图片描述

>> w = fspecial('average', 25);
>> I_filtered = imfilter(I, w, 'replicate');%仅对亮度分量平滑
>> h = cat(3, H, S, I_filtered);
>> f = hsi2rgb(h);
>> imshow(f)    

这里写图片描述

>> fR_filtered = imfilter(fR, w, 'replicate');
>> fG_filtered = imfilter(fG, w, 'replicate');
>> fB_filtered = imfilter(fB, w, 'replicate');
>> g = cat(3, fR_filtered, fG_filtered, fB_filtered);%分别平滑RGB分量
>> imshow(g)    

这里写图片描述

>> imshow(g)
>> H_filtered = imfilter(H, w, 'replicate');
>> S_filtered = imfilter(S, w, 'replicate');
>> h = cat(3, H_filtered, S_filtered, I_filtered);%分别平滑HSI分量
>> f = hsi2rgb(h);
>> imshow(f)     

这里写图片描述

彩色图像锐化

>> f = imread('D:\picture\MATLAB\flower.png');
>> w = fspecial('average',5);
>> fb = imfilter(f, w, 'replicate');
>> lapmask = [1 1 1; 1 -8 1; 1 1 1]; %拉普拉斯滤波器模板
>> fb = tofloat(fb);
>> fen = fb - imfilter(fb, lapmask, 'replicate');
>> subplot(121), imshow(fb), title('模糊图像')
>> subplot(122), imshow(fen), title('拉普拉斯算子增强')

这里写图片描述

直接在RGB向量空间的处理

使用梯度进行彩色边缘检测

  • 自定义函数colorgrad:
    语法:[VG, A, PPG] = colorgrad(f, T)
    其中,f是一幅RGB图像,T是区间[0, 1]内的一个可选阀值(默认为0);VG是RGB向量梯度,A是以弧度计的角度图像,PPG是通过对各个彩色平面的二维梯度图像求和形成的梯度图像。
>> f1 = imread('D:\picture\MATLAB\冈萨雷斯数字图像处理MATLAB版图片\dipum_images_ch06\box1.tif');
>> f2 = imread('D:\picture\MATLAB\冈萨雷斯数字图像处理MATLAB版图片\dipum_images_ch06\box2.tif');
>> f3 = imread('D:\picture\MATLAB\冈萨雷斯数字图像处理MATLAB版图片\dipum_images_ch06\box3.tif');
 >> f = cat(3, f1, f2, f3);
>> subplot(221), imshow(f1)
>> subplot(222), imshow(f2)
>> subplot(223), imshow(f3)
>> subplot(224), imshow(f), title('合并后的RGB')    
![这里写图片描述](http://img.blog.csdn.net/20170629201239218?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzgzMTEwNDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
>> [VG, A, PPG] = colorgrad(f);
>> subplot(121), imshow(VG), title('在RGB向量空间中直接计算的梯度')
>> subplot(122), imshow(PPG), title('分别计算每幅RGB图像的二维梯度并将结果相加得到的合成梯度')   
![这里写图片描述](http://img.blog.csdn.net/20170629201916493?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzgzMTEwNDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
>> f = imread('D:\picture\MATLAB\flower.png');
>> [VG, A, PPG] = colorgrad(f);
>> imshow(VG)
>> imshow(VG)
>> subplot(141), imshow(f), title('RGB图像')
>> subplot(142), imshow(VG), title('在RGB中计算梯度')
>> subplot(143), imshow(PPG), title('合成梯度')
>> subplot(144), imshow(abs(VG - PPG)), title('绝对差') 
![这里写图片描述](http://img.blog.csdn.net/20170629202840879?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzgzMTEwNDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

在RGB向量空间中进行图像分割

  • 自定义函数colorseg实现图像分割

    语法: S = colorseg(method, f, T, parameters)
    其中,method不是’euclidean’就是’mahalanobis’,f是待分割的RGB彩色图像,T是阀值。选择’euclidean’时,输入参数是m(均值),选择’mahalanobis’时,输入参数是m和C(协方差矩阵)。输出S是二值图像。

  • roipoly函数生成一个交互选择的区域二值模板

>> f = imread('D:\picture\MATLAB\冈萨雷斯数字图像处理MATLAB版图片\dipum_images_ch06\MARS.tif');
>> mask = roipoly(f);
>> red = immultiply(mask, f(:, :, 1));
>> green = immultiply(mask, f(:, :, 2));
>> blue = immultiply(mask, f(:, :, 3));
>> g = cat(3, red, green, blue);
>> subplot(121), imshow(f), title('原图')
>> subplot(122), imshow(g), title('切割后的图像')             

这里写图片描述

2013-01-31 17:21:51 www_doling_net 阅读数 6051

5.14 图像频域处理

在图像处理和分析中,经常会将图像从图像空间转换到其他空间中,并利用这些空间的特点进行对转换后图像进行分析处理,然后再将处理后的图像转换到图像空间中,这称之为图像变换。在一些图像处理和分析中通过空间变换往往会取得更有效的结果。图像频域处理是指将图像从图像空间转换到频域空间进行处理的过程。最常用的频域转换是傅里叶变换。对于傅里叶变换的理论内容不是这里讨论的重点,读者可以从网上找到大量的资料。傅里叶变换的计算量较大,人们为了提高速度,提出了快速傅里叶变换,并得到了广泛的应用。下面我们首先来学习一下VTK中的快速傅里叶变换。

5.14.1 快速傅里叶变换

快速傅里叶变换(Fast Fourier Transform),简称做FFT。它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。傅里叶变换是可逆的,其逆变换为RFFT。FFT在数字图像处理中有着广泛的应用,例如数字图像频域滤波,去噪,增强等等。 目前VTK中两变换都已经实现,对应的类分别为vtkImageFFT和vtkImageRFFT。下面代码演示了怎样对图像进行傅里叶变换,以及将傅里叶变换结果进行逆变换。

vtkImageFFT和vtkImageRFFT的输入为实数或者复数数据,输出都为复数数据。因此,vtkImageFFT与vtkImageRFFT的输出结果不能直接显示,因为VTK会将其当做彩色图像显示,需要通过vtkImageExtractComponents提取某一组分图像显示。

VTK频率域的图像处理步骤如下:

 

图5.35VTK频率域的图像处理步骤

下面代码说明了怎样对一副图像进行快速傅里叶变换和逆变换。

 

1:      vtkSmartPointer<vtkJPEGReader>reader =

   2:         vtkSmartPointer<vtkJPEGReader>::New();

   3:     reader->SetFileName ( " lena2.jpg" );

   4:     reader->Update();

   5:  

   6:     vtkSmartPointer<vtkImageFFT> fftFilter =

   7:         vtkSmartPointer<vtkImageFFT>::New();

   8:     fftFilter->SetInputConnection(reader->GetOutputPort());

   9:     fftFilter->Update();

  10:  

  11:     vtkSmartPointer<vtkImageExtractComponents> fftExtractReal =

  12:         vtkSmartPointer<vtkImageExtractComponents>::New();

  13:     fftExtractReal->SetInputConnection(fftFilter->GetOutputPort());

  14:     fftExtractReal->SetComponents(0);

  15:  

  16:     vtkSmartPointer<vtkImageCast> fftCastFilter =

  17:         vtkSmartPointer<vtkImageCast>::New();

  18:     fftCastFilter->SetInputConnection(fftExtractReal->GetOutputPort());

  19:     fftCastFilter->SetOutputScalarTypeToUnsignedChar();

  20:     fftCastFilter->Update();

  21:  

  22:     vtkSmartPointer<vtkImageRFFT> rfftFilter =

  23:         vtkSmartPointer<vtkImageRFFT>::New();

  24:     rfftFilter->SetInputConnection(fftFilter->GetOutputPort());

  25:     rfftFilter->Update();

  26:  

  27:     vtkSmartPointer<vtkImageExtractComponents> ifftExtractReal =

  28:         vtkSmartPointer<vtkImageExtractComponents>::New();

  29:     ifftExtractReal->SetInputConnection(rfftFilter->GetOutputPort());

  30:     ifftExtractReal->SetComponents(0);

  31:  

  32:     vtkSmartPointer<vtkImageCast> rfftCastFilter =

  33:         vtkSmartPointer<vtkImageCast>::New();

  34:     rfftCastFilter->SetInputConnection(ifftExtractReal->GetOutputPort());

  35:     rfftCastFilter->SetOutputScalarTypeToUnsignedChar();

  36:     rfftCastFilter->Update();

 

首先建立一个JPEG图像reader来读取一副灰度图像。然后定义一个vtkImageFFT指针,直接接收reader的输出即原图像数据作为输入进行二维快速傅里叶变换。其输出为一个像素类型为复数的vtkImageData数据,即每个像素值为两个组分(Component):复数实部和虚部。因此如果直接显示这个vtkImageData,会发现是一个彩色图像。如果需要显示频域图像,需要通过vtkImageExtractComponents类来提取某一个组分图像来显示。上例中通过定义vtkImageExtractComponents类指针,利用函数SetComponents(0)指定提取实部图像显示;由于vtkImageActor类仅支持unsigned char数据类型的图像,利用vtkImageCast类的SetOutputScalarTypeToUnsignedChar()指定输出类型为unsigned char,将FFT结果图像转换为需要的类型。

对于逆变换的过程也是类似。首先定义vtkImageRFFT指针,并接收输入为vtkImageFFT指针的输出,调用Update执行函数完成快速傅里叶逆变换。vtkImageRFFT的输出同样为一副复数图像,通常不能直接显示或者进行其他操作。对于傅里叶逆变换的图像中虚数部分值为0,实数部分图像即为重建的原始图像。因此再次利用vtkImageExtractComponents提取实数部分图像,并通过vtkImageCast的SetOutputScalarTypeToUnsignedChar()将图像转换为unsigned char类型进行显示。下图为计算结果。

 

图5.36 快速傅立叶变换

图像通过FFT变换到频域后,可以通过改变不同的频率分量来对图像进行处理。图像频域处理的步骤是,先将空域图像通过FFT变换到频域图像,设计一个滤波器对不同频率的频域分量进行处理,将处理后的频域图像通过IFFT变换回空域中得到处理后的图像。滤波器的设计需要根据具体需求来变化,主要分为两种,低通滤波器和高通滤波器。下面我们来分别介绍。

5.14.2 低通滤波

5.14.2.1 理想低通滤波器

低通滤波是将频域图像中的高频部分滤除而通过低频部分。图像的边缘和噪声对应于频域图像中的高频部分,而低通滤波的作用即是减弱这部分的能量,从而达到图像平滑去噪的目的。最简单的低通滤波器是理想低通滤波器,基本思想是给定一个频率阈值,将高于该阈值的所有部分设置为0,而低于该频率的部分保持不变。理想是指该滤波器不能用电子元器件来实现,但是可以通过计算机来模拟。在VTK中定义了理想低通滤波器,下面我们来看下怎么使用该滤波器来对图像进行低通滤波。

 

1:      vtkSmartPointer<vtkJPEGReader>reader =

   2:         vtkSmartPointer<vtkJPEGReader>::New();

  3:     reader->SetFileName("lena2.jpg");

   4:     reader->Update();

   5:  

   6:     vtkSmartPointer<vtkImageFFT> fftFilter =

   7:         vtkSmartPointer<vtkImageFFT>::New();

   8:     fftFilter->SetInputConnection(reader->GetOutputPort());

   9:     fftFilter->Update();

  10:  

  11:     vtkSmartPointer<vtkImageIdealLowPass> lowPassFilter =

  12:         vtkSmartPointer<vtkImageIdealLowPass>::New();

  13:     lowPassFilter->SetInputConnection(fftFilter->GetOutputPort());

  14:     lowPassFilter->SetXCutOff(0.05);

  15:     lowPassFilter->SetYCutOff(0.05);

  16:     lowPassFilter->Update();

  17:  

  18:     vtkSmartPointer<vtkImageRFFT> rfftFilter =

  19:         vtkSmartPointer<vtkImageRFFT>::New();

  20:     rfftFilter->SetInputConnection(lowPassFilter->GetOutputPort());

  21:     rfftFilter->Update();

  22:  

  23:     vtkSmartPointer<vtkImageExtractComponents> ifftExtractReal =

  24:         vtkSmartPointer<vtkImageExtractComponents>::New();

  25:     ifftExtractReal->SetInputConnection(rfftFilter->GetOutputPort());

  26:     ifftExtractReal->SetComponents(0);

  27:  

  28:     vtkSmartPointer<vtkImageCast> castFilter =

  29:         vtkSmartPointer<vtkImageCast>::New();

  30:     castFilter->SetInputConnection(ifftExtractReal->GetOutputPort());

  31:     castFilter->SetOutputScalarTypeToUnsignedChar();

  32:     castFilter->Update();

 

首先读入一副jpg图像,通过vtkImageFFT将图像转换到频域空间。vtkImageIdealLowPass对频域图像做理想低通滤波,需要用户设置每个方向的截断频率,相应的设置函数SetXCutOff()和SetYCutOff()。执行完毕后,需要通过vtkImageRFFT将处理后的频域图像转换至空域图像。需要注意的是,转换后的图像每个像素都是一个复数,需要vtkImageExtractComponents将该图像的第一个分量提出出来显示,否则图像不能正确显示。由于傅里叶变换输入输出的数据类型都是double,为了方便显示,还需要将其转换为Unsigned char类型,这里vtkImageCast负责类型转换。下面是对图像做低通滤波的效果。从结果看,在过滤掉图像的高频部分后,图像变得模糊,丢失了许多细节,另外还可以看到图像会存在一定的振铃效应,这也是理想低通滤波的特点。

 

图5.37 理想低通滤波器

 

5.14.2.2 巴特沃斯低通滤波器

在实际中经常使用的低通滤波器是巴特沃斯滤波器。巴特沃斯滤波器对应的转移函数(可以看做是一个系数矩阵)是:

 

其中D(u,v)表示频域点(u,v)到频域图像原点的距离,称为截止频率,当D(u,v) = 时,H(u,v)=0.5,即对应的频域能量将为原来的一半。因为巴特沃斯低通滤波器在高低频间的过渡平滑,因此不会出现明显的振铃效应。VTK中实现巴特沃斯低通滤波器的类是vtkImageButterworthLowPass,其使用过程如下。

 

   1:     vtkSmartPointer<vtkImageButterworthLowPass> lowPassFilter =

   2:         vtkSmartPointer<vtkImageButterworthLowPass>::New();

   3:     lowPassFilter->SetInputConnection(fftFilter->GetOutputPort());

   4:     lowPassFilter->SetXCutOff(0.05);

   5:     lowPassFilter->SetYCutOff(0.05);

   6:     lowPassFilter->Update();

 

vtkImageButterworthLowPass与理想低通滤波器的使用一样,因此这里只复制了部分代码。为了便于比较,这里设置X和Y方向的截止频率时,与理想低通滤波器设置一致,下面是相应的执行结果。从结果来看,巴特沃斯低通滤波器产生的图像更为平滑,不会出现振铃现象。

 

图5.38 巴特沃斯滤波器

5.14.3 高通滤波

5.14.3.1 理想高通滤波器

高通滤波与低通滤波正好相反,是频域图像的高频部分通过而抑制低频部分。在图像中图像的边缘对应高频分量,因此高通滤波的效果是图像锐化。同样最简单的高通滤波器是理想高通滤波器。通过设置一个频率阈值,将高于该阈值的频率部分通过,而低于阈值的低频部分设置为0。下面来看一下VTK中理想高通滤波的实例。

1:      vtkSmartPointer<vtkJPEGReader>reader =

   2:         vtkSmartPointer<vtkJPEGReader>::New();

   3:     reader->SetFileName("lena2.jpg");

   4:     reader->Update();

   5:  

   6:     vtkSmartPointer<vtkImageFFT> fftFilter =

   7:         vtkSmartPointer<vtkImageFFT>::New();

   8:     fftFilter->SetInputConnection(reader->GetOutputPort());

  9:      fftFilter->Update();

  10:  

  11:     vtkSmartPointer<vtkImageIdealHighPass> highPassFilter =

  12:         vtkSmartPointer<vtkImageIdealHighPass>::New();

  13:     highPassFilter->SetInputConnection(fftFilter->GetOutputPort());

  14:     highPassFilter->SetXCutOff(0.1);

  15:     highPassFilter->SetYCutOff(0.1);

  16:     highPassFilter->Update();

  17:  

  18:     vtkSmartPointer<vtkImageRFFT> rfftFilter =

  19:         vtkSmartPointer<vtkImageRFFT>::New();

  20:     rfftFilter->SetInputConnection(highPassFilter->GetOutputPort());

  21:     rfftFilter->Update();

  22:  

  23:     vtkSmartPointer<vtkImageExtractComponents> ifftExtractReal =

  24:         vtkSmartPointer<vtkImageExtractComponents>::New();

  25:     ifftExtractReal->SetInputConnection(rfftFilter->GetOutputPort());

  26:     ifftExtractReal->SetComponents(0);

  27:  

  28:     vtkSmartPointer<vtkImageCast> castFilter =

  29:         vtkSmartPointer<vtkImageCast>::New();

  30:     castFilter->SetInputConnection(ifftExtractReal->GetOutputPort());

  31:     castFilter->SetOutputScalarTypeToUnsignedChar();

  32:     castFilter->Update();

 

同低通滤波一样,首先将读入图像通过vtkImageFFT转换到频域空间,定义vtkImageIdealHighPass对象,并通过SetXCutOff ()和SetYCutOff() 设置X和Y方向的截止频率。然后通过vtkImageRFFT将处理后的图像转换到空域中,得到高通滤波图像。为了显示的需要,还需要提取图像分量和数据类型的转换,这里与低通滤波一致,不再赘述。下面是理想高通滤波的执行结果。从结果看出高通滤波后图像得到锐化处理,图像中仅剩下边缘。

 

图5.39 理想高通滤波器

5.14.3.2 巴特沃斯高通滤波器

理想高通滤波器不能通过电子元器件来实现,而且存在振铃现象。在实际中最常使用的高通滤波器是巴特沃斯高通滤波器。该滤波器的转移函数是:

 

D(u,v)表示频域中点到频域平面的距离,是截止频率。当D(u,v)大于时,对应的H(u,v)逐渐接近1,从而使得高频部分得以通过;而当D(u,v)小于时,H(u,v)逐渐接近0,实现低频部分过滤。巴特沃斯高通滤波器在VTK中对应vtkImageButterworthHighPass类。下面代码说明了vtkImageButterworthHighPass对图像进行高通滤波。

 

   1:     vtkSmartPointer<vtkImageButterworthLowPass> lowPassFilter =

   2:         vtkSmartPointer<vtkImageButterworthLowPass>::New();

   3:     lowPassFilter->SetInputConnection(fftFilter->GetOutputPort());

   4:     lowPassFilter->SetXCutOff(0.05);

   5:     lowPassFilter->SetYCutOff(0.05);

   6:     lowPassFilter->Update();

 

vtkImageButterworthHighPass与理想高通滤波使用方法一致,这里没有给出傅里叶变换和逆变换代码。这里也需要设置X和Y轴的截止频率,为了便于比较,其截止频域与理想高通滤波设置一致。下图是执行结果。

 

图5.40 巴特沃斯高通滤波器


==========欢迎转载,转载时请保留该声明信息==========

版权归@东灵工作室所有,更多信息请访问东灵工作室


教程系列导航:http://blog.csdn.net/www_doling_net/article/details/8763686

================================================



 

没有更多推荐了,返回首页