计算机视觉学习记录(一)

计算机视觉学习记录(一)

最近在学习《python计算机视觉编程》这本书,在此记录一下学习过程。

基本的图像操作和处理

打开图片的方式

PIL: Image.open
matplotlib: plt.imread
OPENCV: cv.imread

from PIL import Image
import matplotlib.pyplot as plt
import cv2

img1 = Image.open('G:/qycache/picture/1.jpg')
img2 = plt.imread('G:/qycache/picture/1.jpg')
img3 = cv2.imread('G:/qycache/picture/1.jpg')

不同的图片打开方式 所得到的结果有所不同

plt.figure()
plt.subplot(1,3,1)
plt.title('PIL')
plt.imshow(img1)
plt.subplot(1,3,2)
plt.title('matplotlib')
plt.imshow(img2)
plt.subplot(1,3,3)
plt.title('opencv')
plt.imshow(img3)

plt.show()

在这里插入图片描述
cv2.imshow读取图片的NumPy arrays数组是以 BGR order形式保存的,而Matplotlib中的plt.imshow 是以RGB顺序保存的。

将opencv图片的BGR格式转换为RGB格式:

image = Image.fromarray(cv2.cvtColor(img3,cv2.COLOR_BGR2RGB))


第二张图即为转换后的RGB图片。

图像的颜色转换用convert() 实现,如果要读取一张图片,并将其转换为灰度图,只需加上convert(‘L’)

pil_im = Image.open('G:/qycache/picture/1.jpg').convert('L')

在这里插入图片描述

对图像进行处理

保存图像

通过save()方法,PIL可以将图片保存为多种格式的文件。

缩略图

使用PIL可以很方便地创建缩略图。thumbnail()方法接受一个元组参数(该参数指定生成缩略图的大小),然后将图像转换成符合元组参数指定大小的缩略图。
接下来我们将之前的图片转化为最长边为128像素的缩略图:

img1.thumbnail((128,128))

在这里插入图片描述

复制和粘贴图像区域

使用crop()方法从一幅图像中裁剪指定区域:

box = (750,200,1250,500)#使用四元组指定,四元组的坐标依次是 左、上、右、下#
region = img1.crop(box)#crop指令  裁剪指定区域#

在这里插入图片描述
PIL中指定坐标系的左上角坐标为(0,0)。

旋转上述代码获取的区域,使用paste()的方法将该区域放回去:

region1 = region.transpose(Image.ROTATE_180) #旋转获取的区域#
img1.paste(region1,box) #使用paste将该区域放回去
imshow(img1)
show()

在这里插入图片描述

调整图像尺寸

使用resize()的方法可以调整一幅图像的尺寸。其参数是一个元组,用来指定新图像的大小:

out = img1.resize((128,128))

在这里插入图片描述
旋转图像可以调用rotate()方法,使用逆时针方式表示旋转角度。

out = img1.rotate(45)

在这里插入图片描述

Matplotlib

绘制图像、点和线

当我们想用点和线来表示一些事物,比如说兴趣点、对应点以及检测出的物体时,可以使用Matplotlib 中的Pylab接口。

img1 = array(Image.open('G:/qycache/picture/1.jpg')) #读取图像到数组中#

x = [500,500,1000,1000]
y = [200,800,200,800]
plot(x,y,'r*') #使用红色星状标记绘制点
plot(x[:2],y[:2],'w-') #使用白色实线连接前两个点

在这里插入图片描述
如果不需要显示图像坐标轴,可以使用以下命令:

axis('off')

绘图时,可以选择多种颜色和样式。常见的颜色指令如表1-1所示:
表1-1

指令颜色
‘b’蓝色
‘g’绿色
‘r’红色
‘c’青色
‘m’品红
‘y’黄色
‘k’黑色
‘w’白色

常见的基本线型指令如表1-2所示:
表1-2

指令线型
‘-’实线
‘–’虚线
‘:’点线

常见的基本绘制标记格式指令如表1-3所示:
表1-3

指令标记
‘.’
‘o’圆圈
‘s’正方形
‘*’星形
‘+’加好
‘x’叉号

使用示例:

plot(x,y,'go-')
plot(x,y,'ks:')

图像轮廓和直方图

绘制图像轮廓需要对每个坐标[x,y]的像素施加同一个阈值,首先需要将图像灰度化,再显示轮廓图像。
图像的直方图用来表征该图像像素值的分布情况。用一定数目的小区间(bin)来指定表征像素值的范围,每个小区间内会得到落入该小区间表示范围的像素数目。该灰度图像的直方图可以使用hist()函数绘制。

img1 = array(Image.open('G:/qycache/picture/1.jpg').convert('L'))

figure()#新建一个图像
gray() #不使用颜色信息
contour(img1, origin = 'image')
axis('equal')
axis('off')
figure()
hist(img1.flatten(),128)
axis('off')

在这里插入图片描述
hist()函数的第二个参数指定小区间的数目。hist()函数只接受一维数组作为输入,在绘制图像直方图之前,先使用flatten()方法对图像进行压平处理,将任意数组按照行优先准则转换成一维数组。

交互式标注

有时用户需要和某些应用交互,例如在图像中标记一些点或标注一些训练数据。Pylab库中的ginput()函数可以实现交互式标注。

img1 = array(Image.open('G:/qycache/picture/1.jpg'))
imshow(img1)
print('Please click 3 points')
x = ginput(3)
print('you clicked:',x)

首先绘制一幅图像,等待用户在绘图窗口的图像区域点击3次,程序将点击的坐标[x,y]自动保存在x列表里。

Numpy

Numpy中数组对象是多维的,可以用来表示向量、矩阵和图像。一个数组对象很像一个列表,但是数组中所有的元素必须具有相同的数据类型。

img= array(Image.open('G:/qycache/picture/1.jpg'))
print(pil_im.shape,pil_im.dtype)
img1 = array(Image.open('G:/qycache/picture/1.jpg').convert('L'),'f')
print(pil_im1.shape,pil_im1.dtype) 

输出为:
在这里插入图片描述
每行的第一个元组表示图像数组的大小(行、列、颜色通道),紧接着的字符串表示数组元素的数据类型。
图像通常被编码为无符号八位整数(uint8);在对图像进行灰度化处理的同时,使用额外的参数’f’,将数据类型转化为浮点型;由于灰度图像没有颜色信息,在形状元组中,它只有两个数值。

数组中元素可以使用下标访问。位于坐标i,j,以及颜色通道为k的像素值可以像下面这样访问:

value = im[i,j,k]

多个数组元素可以使用数组切片方式访问。返回以指定间隔下标访问该数组的元素值。

im[i,:] = im[:,j] #将第j行的数值赋给第i行
im[:,i] = 100 # 将第i列的所有数值设为100
im[:100,:50].sum() # 计算前100行、前50列所有数值的和
im[50:100,50:100] #50~100行,50~100列(不包括第100行和第100列)
im[i].mean() #第i行所有数值的平均值
im[:,-1] #最后一列
im[-2,:](or im[-2]) #倒数第二行

灰度变换

将图像读入numpy 数组后,可以对其进行任意数学操作。

im2 = 255 - pil_im #反相处理
im3 = (100.0/255) * pil_im +100 #像素值变换到100-200区间
im4 = 255.0 * (pil_im/255.0)**2 #像素值平方后的图像
print(int(im2.min()),int(im2.max()))#查看图像最小和最大像素值

在这里插入图片描述
array()变换的相反操作可以使用PIL的formarray()函数完成:

pil_im = Image.fromarray(im)

安全起见,在创建PIL图像之前,应该先将数据格式转换回来。

pil_im = Image.fromarray(uint8(im))

图像缩放

图像缩放可以使用resize函数。

pil_im = array(Image.open('G:/qycache/picture/1.jpg'))
pil_im1 = Image.fromarray(uint8(pil_im))
pil_im1 = pil_im1.resize((600,300),Image.ANTIALIAS)

直方图均衡化

直方图均衡化是指将一幅图像的灰度直方图变平,使变换后的图像中每个灰度值的分布概率都相同。直方图均衡化通常是对图像灰度值归一化的很好的方法,可以增强图像的对比度。
直方图均衡化的变换函数是图像中像素值的累积分布函数(cumulative distribution function),将像素值的范围映射到目标范围内。

def histeq(im, nbr_bins = 256):
'''对一幅灰度图像进行直方图均衡化'''
    #计算图像直方图
    imhist,bins = histogram(im.flatten(), nbr_bins)
    cdf = imhist.cumsum()
    cdf = 255 * cdf / cdf[-1] #归一化
    #使用累积分布函数的线性插值,计算新的像素值
    im2 = interp(im.flatten(), bins[:-1],cdf)
    return im2.reshape(im.shape),cdf

im2,cdf = histeq(pil_im)

函数有两个输入参数,一个是灰度图像,一个是直方图中使用小区间的数目。函数返回直方图均衡化后的图像以及用来做像素值映射的累积分布函数。
在这里插入图片描述
不使用颜色信息:
在这里插入图片描述
可以看出均衡化后的图像对比度增强了。

关于直方图均衡化的相关解析可以参见以下链接:
有关直方图均衡化的解析说明

图像平均

图像平均是减少图像噪声的一种方式。可以从图像列表中计算出一幅平均图像。假设所有的图像具有相同大小,将这些图像相加后除以图像数目,就可以得到平均图像。

def compute_average(imlist):
    '''计算图像列表的平均图像'''

    #打开第一幅图像,将其存储在浮点型数据中
    averageim = array(Image.open(imlist[0]),'f')

    for imname in imlist[1:]:
        try:
            averageim += array(Image.open(imname))
        except:
            print(imname + '...skipped')
    averageim /= len(imlist)

    #返回uint8类型的平均图像
    return array(averageim, 'uint8')

图像主成分分析PCA

PCA的作用是降维。可以在使用尽可能少维数的前提下,尽量多地保持训练数据的信息。PCA产生的投影矩阵可以被视为将原始坐标变换到现有的坐标系,坐标系中的各个坐标按照重要性递减排列。
对图像进行PCA变换之前,需要使用Numpy库中的flatten()函数将图像转换成一维向量。
【将变平的图像堆积起来,可以得到一个矩阵,矩阵的一行表示一幅图像】在计算主方向之前,所有的行图像按照平均图像进行了中心化。通常使用SVD奇异值分解方法来计算主成分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值