一、認識影像 你需要選取任意一張圖片做以下操作,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需要大量練習,多看多讀后再動手, 影像處理的實質是對構成其影像的像素點進行操作,影像處理本質上還是數學變換,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/291166.html
標籤:AI
下一篇:機器學習-支持向量機(基礎)
