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

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

一、图像的表示方法

  • 二值图像: 每个像素点不是白色就是黑色;一个像素点只要一个bit位就能表示;用0或1表示每个像素点。
  • 灰度图像: 图像只有一种颜色,比如图像可以是红色,可以是灰色,可以蓝色,可以是绿色等等,但不管什么颜色都是只有一种颜色。但是这一种颜色我们给它分成了256个等级,就是256个灰度级,可以理解成256个不同程度的明暗度。比如一张红色的灰度图像,像素值=0就是最暗,黑色,像素值=255就是最亮,就是最亮的红色。255中明暗度正好可以用8位也就是1字节byte表示。
  • 彩色图像: 图像是彩色的,图像的每个像素点都是由三种颜色混合而成。这三种颜色是R G B, 每种颜色的取值都在0-255之间。每种颜色是一个通道,所以彩图一般都是3通道。少数图像是4通道,因为还有一个0-1之间的透明度。

二、像素处理

scss 复制代码
#例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()     #这么图片窗口都统统消失吧

请看下面图像数据长的样子吧:
 [[0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]] 

请看切出来像素的值,是不是从0变为255了:
 [[  0   0   0 255 255 255   0   0   0   0]
 [  0   0   0 255 255 255   0   0   0   0]
 [  0   0   0 255 255 255   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0]]

#例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通道的蓝光强度值。

scss 复制代码
#例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()
scss 复制代码
#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()

css 复制代码
#例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]
python 复制代码
#例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()

四、ROI, Region of Interest, 感兴趣区域

python 复制代码
#例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()

说明:通道顺序改变后,图像的显示效果也发生了改变。

六、获取图像属性

python 复制代码
#例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:文本在图像中的放置位置(左下角);字体、字体大小、颜色、宽度。

scss 复制代码
#例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()
相关推荐
小陈phd3 小时前
多模态大模型学习笔记(二)——机器学习十大经典算法:一张表看懂分类 / 回归 / 聚类 / 降维
学习·算法·机器学习
@––––––3 小时前
力扣hot100—系列4-贪心算法
算法·leetcode·贪心算法
CoovallyAIHub4 小时前
让本地知识引导AI追踪社区变迁,让AI真正理解社会现象
深度学习·算法·计算机视觉
CoderCodingNo4 小时前
【GESP】C++ 二级真题解析,[2025年12月]第一题环保能量球
开发语言·c++·算法
yumgpkpm4 小时前
预测:2026年大数据软件+AI大模型的发展趋势
大数据·人工智能·算法·zookeeper·kafka·开源·cloudera
CoovallyAIHub4 小时前
AAAI 2026这篇杰出论文说了什么?用LLM给CLIP换了个“聪明大脑”
深度学习·算法·计算机视觉
Physicist in Geophy.4 小时前
一维波动方程(从变分法角度)
线性代数·算法·机器学习
im_AMBER4 小时前
Leetcode 115 分割链表 | 随机链表的复制
数据结构·学习·算法·leetcode
Liue612312314 小时前
【YOLO11】基于C2CGA算法的金属零件涂胶缺陷检测与分类
人工智能·算法·分类