opencv 入门

本文通过OpenCV库展示了图像处理的各种操作,包括图像通道分离、色彩空间转换(BGR到HSV、YUV、YCrCb和灰度)、形态学处理(开运算、闭运算、寻找轮廓)、仿射变换(缩小、平移、旋转)和透视变换。此外,还探讨了图像平滑处理(高斯模糊、Box滤波、中值滤波)和阈值操作。最后,通过图像轮廓检测来识别直线、圆、椭圆等图形元素,并进行了距离计算。
摘要由CSDN通过智能技术生成

一、认识图像 你需要选取任意一张图片做以下操作。1.分离出图像的三个通道(BGR)2.多图像进行色彩空间转换(不限定类型,至少两种)3.对你选择的图片进行不少于五种的图像处理操作(如形态学处理、仿射变换等等,其他的靠自己去探索学习) 这些效果都可以由opencv的函数实现,运行程序时都需要显示出来。

引入库

import cv2
import numpy as np
import matplotlib.pyplot as plt

1.分离出图像的三个通道(BGR)


def char_rgb(img):
    b,g,r=cv2.split(img)
    return cv2.merge([r,g,b])
img=cv2.imread(r'x.png')
b,g,r=cv2.split(img)
zeros = np.zeros(img.shape[:2], dtype = "uint8")

plt.subplot(221)
plt.title("blue")

merged = cv2.merge([zeros, zeros, b])
plt.axis("off")
plt.imshow(merged)

plt.subplot(222)
plt.title("green")
merged = cv2.merge([zeros, g, zeros])
plt.axis("off")
plt.imshow(merged)
merged = cv2.merge([r, zeros, zeros])
plt.subplot(223)
plt.title("red")
plt.axis("off")
plt.imshow(merged)

plt.subplot(224)
merged = cv2.merge([r, g,b])
plt.title("merge")
plt.axis("off")
plt.imshow(merged)

plt.show()

在这里插入图片描述

2.多图像进行色彩空间转换

plt.figure("色彩空间转换", figsize=(12, 8))
img=cv2.imread(r'x.png')

plt.subplot(221)
img1=img.copy()
hsv = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
plt.title("hsv")
plt.axis("off")
plt.imshow(hsv[:,:,[2,1,0]])

plt.subplot(222)
img2=img.copy()
yuv = cv2.cvtColor(img2, cv2.COLOR_BGR2YUV)
plt.title("yuv")
plt.axis("off")
plt.imshow(yuv[:,:,[2,1,0]])

plt.subplot(223)
img3=img.copy()
ycrcb  = cv2.cvtColor(img3,cv2.COLOR_BGR2YCrCb)
plt.title("ycrcb")
plt.axis("off")
plt.imshow(ycrcb[:,:,[2,1,0]])

plt.subplot(224)
img4=img.copy()
img = cv2.cvtColor(img4,cv2.COLOR_BGR2GRAY)
plt.title("gray")
plt.axis("off")
GRAY = np.concatenate((np.expand_dims(img, axis=2), np.expand_dims(img, axis=2), np.expand_dims(img, axis=2)), axis=-1)
plt.imshow(GRAY)


plt.show()

在这里插入图片描述

3.图像处理操作

###(1)形态学处理

#开运算
img=cv2.imread(r'x.png')
img1=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转为灰度图;
ret2, th2 = cv2.threshold(img1, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)#二值化处理
for i in range(2000):  # 添加椒盐噪声
    _x = np.random.randint(0, th2.shape[0])
    _y = np.random.randint(0, th2.shape[1])
    th2[_x][_y] = 255
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.morphologyEx(th2, cv2.MORPH_OPEN, kernel)  # 开运算函数:先进行腐蚀再膨胀
plt.subplot(121)
plt.imshow(th2)
plt.axis('off')

plt.subplot(122)
plt.imshow(erosion)
plt.axis('off')
plt.show()

在这里插入图片描述

#闭运算
img=cv2.imread(r'x.png',0)
#img1=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)转为灰度图
ret2, th2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)#二值化处理

for i in range(20000):  # 添加椒盐噪声
    _x = np.random.randint(0, th2.shape[0])
    _y = np.random.randint(0, th2.shape[1])
    th2[_x][_y] = 0
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.morphologyEx(th2, cv2.MORPH_CLOSE, kernel) # 闭运算函数:先进行膨胀再腐蚀
plt.subplot(121)
plt.imshow(th2)
plt.axis('off')

plt.subplot(122)
plt.imshow(erosion)
plt.axis('off')
plt.show()

在这里插入图片描述

# 寻找轮廓
img = cv2.imread(r'x.png', 0)
ret, th = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
kernel = np.ones((5, 5), np.uint8)
# morphology  形态学
gradient = cv2.morphologyEx(th, cv2.MORPH_GRADIENT,kernel)  # morph gradient 形态梯度
plt.subplot(121)
plt.imshow(th)
plt.axis('off')

plt.subplot(122)
plt.imshow(gradient)
plt.axis('off')
plt.show()

在这里插入图片描述

###(2)仿射变换

img = cv2.imread(r'x.png')
h,w,c=img.shape
#缩小2倍
A1=np.array([[0.5,0,0],[0,0.5,0]],np.float32)
A2=cv2.warpAffine(img,A1,(w,h),borderValue=126)
#缩小后平移
B1=np.array([[0.5,0,w/4],[0,0.5,h/4]],np.float32)
B2=cv2.warpAffine(img,B1,(w,h),borderValue=126)
#使图像旋转
C1=cv2.getRotationMatrix2D((w/2.0,h/2.0),30,1)
C2=cv2.warpAffine(img,C1,(w,h),borderValue=126) 
#仿射
p1 = np.float32([[0,0], [w-1,0], [0,h-1]])
p2 = np.float32([[0,h*0.3], [w*0.8,h*0.2], [w*0.15,h*0.7]])
M = cv2.getAffineTransform(p1, p2)
dst = cv2.warpAffine(img, M, (w,h))
plt.subplot(141)
plt.imshow(A2[:,:,[2,1,0]])  
plt.axis('off')

plt.subplot(142)
plt.imshow(B2[:,:,[2,1,0]])  
plt.axis('off')

plt.subplot(143)
plt.imshow(C2[:,:,[2,1,0]])  
plt.axis('off')

plt.subplot(144)
plt.imshow(dst[:,:,[2,1,0]])  
plt.axis('off')

plt.show     

在这里插入图片描述

###(3)透视变换

img = cv2.imread(r'x.png')
rows, cols, channels = img.shape
p1 = np.float32([[0,0], [cols-1,0], [0,rows-1], [rows-1,cols-1]])
p2 = np.float32([[0,rows*0.3], [cols*0.8,rows*0.2], [cols*0.15,rows*0.7], [cols*0.8,rows*0.8]])
M = cv2.getPerspectiveTransform(p1,p2)
dst = cv2.warpPerspective(img, M, (cols, rows))
plt.subplot(141)
plt.imshow(dst[:,:,[2,1,0]])  
plt.axis('off')
plt.show()

在这里插入图片描述

###(4)平滑处理

img = cv2.imread(r'x.png')
img1=img.copy()
for i in range(20000):  # 添加椒盐噪声
    _x = np.random.randint(0, img1.shape[0])
    _y = np.random.randint(0, img1.shape[1])
    img1[_x][_y] = 255

plt.subplot(151)
plt.title('origin')
plt.imshow(img1[:,:,[2,1,0]])
plt.axis('off')

plt.subplot(152)
plt.title('blur')
plt.imshow(cv2.blur(img1, (3, 3))[:,:,[2,1,0]])
plt.axis('off')

plt.subplot(153)
plt.title('Gaussian')
plt.imshow(cv2. GaussianBlur(img1, (5, 5),1)[:,:,[2,1,0]])
plt.axis('off')

plt.subplot(154)
plt.title('box')
plt.imshow(cv2.boxFilter(img,-1,(3,3), normalize=True) [:,:,[2,1,0]])
plt.axis('off')

plt.subplot(155)
plt.title('median')
plt.imshow(cv2.medianBlur(img, 5)[:,:,[2,1,0]])
plt.axis('off')

plt.show()

在这里插入图片描述

3.阈值操作

img = cv2.imread(r'x.png')
img = cv2.GaussianBlur(img, (3, 3), 1)
ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)

titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]

for i in range(6):
    plt.subplot(2,3,i+1),plt.imshow(images[i][:,:,[2,1,0]])
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])

plt.show()

在这里插入图片描述

二、形状探测 在下面这张图片(x.png)中找出直线、圆、椭圆等图形元素,并把他们用有颜色的线条标记出来。如果左下角点(绿色夹角处)到右下角点(绿色夹角处)的真实距离定为10cm,那么左下角点到最高点(绿色圆球处)的距离是多少?

# 读取彩色图片
img = cv2.imread(r'x.png')
# 转换为灰度图片
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 进行二值化处理
ret,binary = cv2.threshold(gray, 224, 255, cv2.THRESH_BINARY_INV)
plt.subplot(121)
plt.imshow( binary)
plt.axis('off')
# 寻找轮廓
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 绘制不同的轮廓
draw = cv2.drawContours(img.copy(),contours,-1,(0,255,255),3)

plt.subplot(122)
plt.imshow(draw[:,:,[2,1,0]])
plt.axis('off')

在这里插入图片描述

len(contours)

3

plt.subplot(131)
plt.imshow(cv2.drawContours(img.copy(),contours[0],-1,(0,255,255),3)[:,:,[2,1,0]])
plt.axis('off')

plt.subplot(132)
plt.imshow(cv2.drawContours(img.copy(),contours[1],-1,(0,255,255),3)[:,:,[2,1,0]])
plt.axis('off')

plt.subplot(133)
plt.imshow(cv2.drawContours(img.copy(),contours[2],-1,(0,255,255),3)[:,:,[2,1,0]])
plt.axis('off')
plt.show()
#故所需数据均在contours[2]

在这里插入图片描述

list_a=np.squeeze(contours[2])  
list_a = list_a[list_a[:,1].argsort()]
list_a.tolist()
min,max=list_a[0][0],list_a[0][0]
for i in list_a:
    
    if i[1]<min:
        min=i[1]
    if i[1]>max:
        max=i[1]    
b=[]        
for i in list_a:
    if i[1]==max:
        b.append(i[0])
b.sort()

x=10/(b[len(b)-1]-b[0])*np.sqrt((max-min)**2+(b[0]-img.shape[1]/2)**2)
print("实际距离:",x,"cm")

在这里插入图片描述

小结: open cv 是对图像处理工具库 ,可以对图像进行各种操作,犹如ps。我觉得学习open cv需要大量练习,多看多读后再动手。 图像处理的实质是对构成其图像的像素点进行操作,图像处理本质上还是数学变换。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值