LiteralliJeff 发表于 2022-9-28 08:57

opencv学习笔记(二):图像处理基本操作

第二章: 图像处理基本操作

一、图像的表示方法

[*]二值图像: 每个像素点不是白色就是黑色;一个像素点只要一个bit位就能表示;用0或1表示每个像素点。
[*]灰度图像: 图像只有一种颜色,比如图像可以是红色,可以是灰色,可以蓝色,可以是绿色等等,但不管什么颜色都是只有一种颜色。但是这一种颜色我们给它分成了256个等级,就是256个灰度级,可以理解成256个不同程度的明暗度。比如一张红色的灰度图像,像素值=0就是最暗,黑色,像素值=255就是最亮,就是最亮的红色。255中明暗度正好可以用8位也就是1字节byte表示。
[*]彩色图像: 图像是彩色的,图像的每个像素点都是由三种颜色混合而成。这三种颜色是R G B, 每种颜色的取值都在0-255之间。每种颜色是一个通道,所以彩图一般都是3通道。少数图像是4通道,因为还有一个0-1之间的透明度。
二、像素处理
#例2.1 生成一个10x10大小的黑色图像,并且对其像素进行修改,显示修改前后的图像,理解数据和图像之间的一一对应关系。
import cv2
import numpy as np
img = np.zeros((10,10), dtype=np.uint8)
print('请看下面图像数据长的样子吧:\n', img, '\n')   #\n表示回车重启一行
cv2.imshow('one', img)         #图像窗口显示图像
img=255               #把img图像上的第0行到第2行,第3列到第5列的像素点切出来,并且给它们赋值为255
print('请看切出来像素的值,是不是从0变为255了:\n', img)
cv2.imshow('two', img)
cv2.waitKey(20000)          #20秒后就执行下面语句吧,程序别老卡在这条语句上了。
cv2.destroyAllWindows()   #这么图片窗口都统统消失吧

#例2.2 读取一个灰度图像,并对其指定的像素进行修改
import cv2                                                 #倒库
lena = cv2.imread(r'C:\Users\25584\Desktop\lena.bmp',0)    #把lena读到内存
cv2.imshow('the first', lena)                              #用一个窗口把lena显示出来
for hang in range(10, 100):       #A               
    for lie in range(80, 200):
      lena=255
cv2.imshow('the second', lena)
cv2.waitKey(20000)
cv2.destroyAllWindows()

[*]A: 代码中使用了一个双层嵌套循环把lena图像数据中的 第10行到第99行、第80列到199列 的数据索引出来,并且把这些数据重新赋值为255.
[*]知识点:
1、容器的概念,range()函数、list列表 等都是容器。是容器就可以对里面的元素进行遍历,也就是进行循环。
2、for循环、嵌套循环,都是基础必须完全熟练。
三、彩色图像基本知识点

我们平时看到的彩色图像,不管什么格式的,一般都是RGB色彩通道模式的图片,就是图片的每个像素都有三个数字,第一个数字是R红色通道的红光强度值,第二个数字是G绿色通道的绿光强度值,第三个数字是B蓝色通道的蓝光的强度值。
但是opencv在读取彩色图片的数据时,是将图片里面的数据以行方向顺序读取,并且以BGR的默认模式存放在数组ndarray中的。就相当于把一张图片从左上角的第一个像素开始,按行依次垂直排列,拍成一条数直的长线,线上的每个点都是三个数字,但这三个数字默认的BGR通道。
image 第一个参数0表示第0行,第二个参数0表示第0列,第三个参数表示第0个通道。由于opencv读出来的三个通道是BGR顺序的,所以第三个参数0在opencv中是切出来的像素点就是image这张图片中的左上角第一个像素点B通道的蓝光强度值。
#例2.3 先生成一个三维全是0的ndarray数组,然后切出第一个通道的数据并改为255,然后再显示这个三维数据图像。依次类推把三个通道都操作一遍。即根据图像的通道操作整张图像。
import numpy as np
import cv2
blue = np.zeros((200, 300, 3), dtype=np.uint8)   #用np.zeros(, dtype=np.uint8)理解这个函数
blue[:,:,0]=255                                  #np.zeros(, dtype=np.uint8)[:,:,0]=255,尝试用小数据切一切认识数据
print(blue)
cv2.imshow('blue', blue)
print('------------------------------------------------')
green = np.zeros((200, 300, 3), dtype=np.uint8)
green[:,:,1]=255
print(green)
cv2.imshow('green', green)
print('------------------------------------------------')
red = np.zeros((200, 300, 3), dtype=np.uint8)
red[:,:,2]=255
print(red)
cv2.imshow('red', red)
print('------------------------------------------------')
colorfull = np.zeros((200, 300, 3), dtype=np.uint8)
colorfull[:,:,0]=255   #蓝色
colorfull[:,:,1]=0       #绿色
colorfull[:,:,2]=255   #红色
print(colorfull)
cv2.imshow('colorfull', colorfull)

cv2.waitKey(10000)
cv2.destroyAllWindows()
#例2.4   观察一张图像的部分像素点的某个通道上的数值改变,这张图像跟着怎么变化。
import numpy as np
import cv2
img = np.zeros((300,300,3),dtype=np.uint8)#数据太多看不明白到底哪些数据被改了,就用小数据实验:img = np.zeros((3,6,3),dtype=np.uint8)
img[:, 0:100, 0]=255   #蓝色通道                                                                   #img[:, 0:1, 0]=255
img[:,100:200, 1]=255    #绿色通道                                                                  #img[:,1:3, 1]=255
img[:, 200:300, 2]=255   #红色通道                                                                   #img[:, 3:6, 2]=255
print(img)
cv2.imshow('img', img)
cv2.waitKey(10000)
cv2.destroyAllWindows()
#例2.5手动生成一张BGR模式的彩色图像
import numpy as np
import cv2
img = np.zeros((2, 4, 3), dtype=np.uint8)
print(img, '\n--------- \n', img, '\n--------- \n', img)
cv2.imshow('img', img)
img=255
img=
img = 3
img = 4
img = 5
print('\n--------- \n', img, '\n--------- \n', img)
cv2.waitKey(10000)
cv2.destroyAllWindows()
#例2.6 读取lenacolor图片,用循环更改图片的某些区域的像素值
import cv2
lena_color = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
cv2.imshow('before', lena_color)
print(lena_color, lena_color, lena_color)
print(lena_color, lena_color)

for i in range(0, 50):
    for j in range(0, 100):
      for k in range(0, 3):
            lena_color=255
            
for i in range(50, 100):
    for j in range(100, 200):
      lena_color=
      
for i in range(100, 150):
    for j in range(200, 300):
      lena_color=0
      
cv2.imshow('after', lena_color)
print(lena_color, lena_color, lena_color, lena_color, lena_color, lena_color)
cv2.waitKey(10000)
cv2.destroyAllWindows()返回:



#2.7 练习函数item()和函数itemset()的用法
import numpy as np
img = np.random.randint(10, 99, size=(5,5), dtype=np.uint8)
print(img, '\n', img.item(3,2))
img.itemset((3,2), 255)
img


[*]np.random.randint(a,b, size, dtype)函数
函数的功能是随机生成一些整数。第一个参数是要生成的数的起始值,第二个参数是最大值,第三个参数是要生成的整数的形状,第四个参数是要生成的数的类型。
[*]函数item(a,b)
函数的功能是索引出要访问的图像的某个像素点。函数返回要索引的像素点的值。
函数有两个参数,第一个参数是像素点的行,第二个参数是像素点的列。
[*]函数itemset((a,b),c) 函数用来修改指定像素点的像素值。本函数直接在原图像上修改,不返回任何值。 函数有两个参数,第一个参数是要修改的像素点,第二个参数是要修改的像素的值。
[*]说明
item()函数和itemset()都是只能索引或者修个一个像素点!!!如果我们想索引或修改一批像素点时,我们就要用循环一个个像素点进行修改!!!
#例2.8 生成一个像素值为随机数的灰度图像
import numpy as np
import cv2
img = np.random.randint(0,256, size=(300, 300), dtype=np.uint8)
img
cv2.imshow('demo', img)
cv2.waitKey(10000)
cv2.destroyAllWindows()
#例2.9 读取灰度图像lena.bmp,并对其像素值进行索引、修改
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lena.bmp', 0)
#修改一个像素点:
print(lena.item(2,3))
lena.itemset((2, 3), 255)      
print(lena.item(2, 3))
#修改一个区域的像素点:
cv2.imshow('xiu gai qian', lena)
for i in range(10, 50):
    for j in range(20, 100):
      lena.itemset((i,j), 255)
cv2.imshow('xiu gai hou', lena)
cv2.waitKey(10000)
cv2.destroyAllWindows()返回:160 255
#例2.10 生成一个像素值为随机数的彩色图像,练习item()函数和itemset()函数:
import numpy as np
img = np.random.randint(10, 99, size=(2,4,3), dtype=np.uint8)
img
img, img, img
img.item(1,2,0), img.item(1,2,1), img.item(1,2,2)
img.itemset((1,2,0), 255), img.itemset((1,2,1), 255), img.itemset((1,2,2), 255)
img, img, img返回:(255, 255, 255)
#例2.11 生成一个像素值为随机数的彩色图像
img = np.random.randint(0, 256, size=(200, 200, 3), dtype=np.uint8)
cv2.imshow('random colorfull img', img)
cv2.waitKey(10000)
cv2.destroyAllWindows()
#例2.12 读取彩色图像lenacolor.png, 并对图像进行修改
import cv2
import numpy as np
lena_color = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
cv2.imshow('xiu gai qian', lena_color)
print(lena_color, lena_color, lena_color)
for i in range(0, 100):
    for j in range(0,200):
      for k in range(0,3):
            lena_color.itemset((i,j,k),255)
cv2.imshow('xiu gai hou', lena_color)   
print(lena_color, lena_color, lena_color)
cv2.waitKey(10000)
cv2.destroyAllWindows()返回:
125 137 226
255 255 255
四、ROI, Region of Interest, 感兴趣区域
#例2.13 获取lena的脸部信息,并将其显示出来
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png', -1)
lena_face = lena    #用切片获取ROI
cv2.imshow('lena', lena)   
cv2.imshow('lena face', lena_face)
cv2.waitKey(10000)
cv2.destroyAllWindows()
#例2.14 给lena的脸部打码
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png', -1)
cv2.imshow('lena', lena)

roi_1 = np.random.randint(0, 256, (180, 130,3), dtype=np.uint8)
lena=roi_1
cv2.imshow('color mask', lena)

roi_2 = np.zeros((180, 130,3),dtype=np.uint8)
roi_2[:,:,:]=255
lena=roi_2
cv2.imshow('white mask', lena)

cv2.waitKey(10000)
cv2.destroyAllWindows()
#例2.15 将一幅图像内的ROI复制到另一幅图像内:给dollar换脸
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lena512.bmp', -1)
dollar = cv2.imread(r'C:\Users\25584\Desktop\dollar.bmp', -1)
cv2.imshow('lena', lena)
cv2.imshow('dollar', dollar)
lena_face = lena
dollar=lena_face
cv2.imshow('dollar2', dollar)
cv2.waitKey(10000)
cv2.destroyAllWindows()
五、通道操作

一个RGB彩色图像,在opencv中,它是按照B通道-G通道-R通道 的顺序存储的。

[*]通道拆分 1、索引方式拆分 2、函数方式拆分
[*]通道合并
#例2.16 编写程序,演示图像通道拆分及通道值改变对彩色图像的影响
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
cv2.imshow('lena', lena)

b_tongdao = lena[:, :, 0]
g_tongdao = lena[:, :, 1]
r_tongdao = lena[:, :, 2]
cv2.imshow('b', b_tongdao)
cv2.imshow('g', g_tongdao)
cv2.imshow('r', r_tongdao)

lena[:, :, 0]=0
cv2.imshow('b_0', lena)
lena[:, :, 1]=0
cv2.imshow('g_0', lena)

cv2.waitKey(20000)
cv2.destroyAllWindows()
#例2.17 使用函数cv2.split()函数拆图像通道, 并显示三个通道图像。
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
b,g,r = cv2.split(lena)
cv2.imshow('b', b)
cv2.imshow('g', g)
cv2.imshow('r', r)
cv2.waitKey(20000)
cv2.destroyAllWindows()
#自主练习:把一张彩图的三个通道数据分别切出来,仍以彩图形式显示图像。
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')

lena1 = lena.copy()
lena1[:,:,1:3]=0
cv2.imshow('b', lena1)

lena2 = lena.copy()
lena2[:,:,0]=0
lena2[:,:,2]=0
cv2.imshow('g', lena2)

lena3 = lena.copy()
lena3[:,:,0:2]=0
cv2.imshow('r', lena3)

cv2.waitKey(20000)
cv2.destroyAllWindows()
#例2.18 通道合并,使用函数cv2.merge()函数合并通道
import cv2
lena = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
b,g,r = cv2.split(lena)
bgr = cv2.merge()
rgb = cv2.merge()

cv2.imshow('bgr', bgr)
cv2.imshow('rgb', rgb)

cv2.waitKey(20000)
cv2.destroyAllWindows()说明:通道顺序改变后,图像的显示效果也发生了改变。
六、获取图像属性
#例2.19 观察图像的常用属性值
import cv2
lena_gray = cv2.imread(r'C:\Users\25584\Desktop\lena.bmp',0)#参数0表示图像被调整为单通道的灰度图像
lena_color = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')#彩色图像
lena_gray.shape
lena_color.shape

lena_gray.size
lena_color.size

lena_gray.dtype
lena_color.dtype返回:dtype('uint8')
说明:
shape属性是用来判断一幅图像是灰度图像还是彩色图像。
size属性返回的是图像的像素数目,即图像的'行x列x通道数'。灰度图像的通道数为1,彩色图像的通道数为3。
dtype属性返回图像的数据类型。
七、在图像上绘制几何图形

绘制直线:cv.line(img, start, end, color, thickness)
img:要绘制直线的图像;start,end直线的起点和终点;color线条的颜色;thickness线条的宽度。
绘制圆形:cv.circle(img, centerpoint, r, color, thickness)
thickness表示线条的宽度,当这个参数=-1时生成闭合图案并填充颜色。
绘制矩形:cv.rectangle(img, leftupper, rightdown, color, thickness)
设置矩形的左上角和右下角坐标即可。
在图像中添加文字:cv.putText(img, text, station, font,fontsize, color, thickness, cv.LINE_AA)
text:要写入的文字;station:文本在图像中的放置位置(左下角);字体、字体大小、颜色、宽度。
#例2.20 生成一个全黑的图像,在图像上绘制上面的图形并添加文字
import numpy as np
import cv2
import matplotlib.pyplot as plt
img = np.zeros((300, 300, 3), np.uint8)

cv2.line(img, (0,20), (300, 200), (255,0,0),5)   #线段起点、终点、颜色、粗细
cv2.rectangle(img, (50, 80), (120, 250), (0,255,0), 3)#左上角坐标,右下角坐标
cv2.circle(img, (200, 200),60, (0,0,255),-1)    #圆心坐标,半径,-1表示圆形里面填充颜色。
cv2.putText(img, 'opencv', (70,40), cv2.FONT_HERSHEY_SIMPLEX, 2, (255,255,255), 2)   #左下角坐标

plt.imshow(img[:,:,::-1])
plt.title('case show')
plt.show()
页: [1]
查看完整版本: opencv学习笔记(二):图像处理基本操作