【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[0:3,3:6]=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[hang, lie]=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行,第二个参数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([4, 5, 3], dtype=np.uint8)理解这个函数
blue[:,:,0]=255                                  #np.zeros([4, 5, 3], 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[0,3], '\n--------- \n', img[1, 2, 2])
cv2.imshow('img', img)
img[0,3]=255
img[0,0]=[66,77,88]
img[1,1,1] = 3
img[1,2,2] = 4
img[0,2,0] = 5
print('\n--------- \n', img, '\n--------- \n', img[1,2,2])
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[0,0,0], lena_color[0,0,1], lena_color[0,0,2])
print(lena_color[50,0], lena_color[100,0])

for i in range(0, 50):
    for j in range(0, 100):
        for k in range(0, 3):
            lena_color[i,j,k]=255
            
for i in range(50, 100):
    for j in range(100, 200):
        lena_color[i,j]=[128, 128, 128]
        
for i in range(100, 150):
    for j in range(200, 300):
        lena_color[i,j]=0
        
cv2.imshow('after', lena_color)
print(lena_color[0,0], lena_color[0,0,0], lena_color[0,0,1], lena_color[0,0,2], lena_color[50,0], lena_color[100,0])
cv2.waitKey(10000)
cv2.destroyAllWindows()
返回:
125 137 226
[114 136 230] [ 75  55 155]
[255 255 255] 255 255 255 [114 136 230] [ 75  55 155]
#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
[[97 14 87 30 14]
 [63 13 21 10 71]
 [45 45 37 51 44]
 [97 95 61 17 37]
 [17 31 73 49 26]] 
 61
array([[ 97,  14,  87,  30,  14],
       [ 63,  13,  21,  10,  71],
       [ 45,  45,  37,  51,  44],
       [ 97,  95, 255,  17,  37],
       [ 17,  31,  73,  49,  26]], dtype=uint8)

  • 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[1,2,0], img[1,2, 1], img[1,2,2]
    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[1,2,0], img[1,2, 1], img[1,2,2]
    (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[0,0,0], lena_color[0,0,1], lena_color[0,0,2])
    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[0,0,0], lena_color[0,0,1], lena_color[0,0,2])
    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[220:400, 220:350]    #用切片获取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[220:400, 220:350]=roi_1
    cv2.imshow('color mask', lena)
    
    roi_2 = np.zeros((180, 130,3),dtype=np.uint8)
    roi_2[:,:,:]=255
    lena[220:400, 220:350]=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[220:400, 250:350]
    dollar[160:340, 200:300]=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([b,g,r])
    rgb = cv2.merge([r,g,b])
    
    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()


  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值