1. 程式人生 > 程式設計 >openCV提取影象中的矩形區域

openCV提取影象中的矩形區域

改編自詳解利用OpenCV提取影象中的矩形區域(PPT螢幕等) 原文是c++版,我改成了python版,供大家參考學習。
主要思想:邊緣檢測—》輪廓檢測—》找出最大的面積的輪廓—》找出頂點—》投影變換

import numpy as np
import cv2
# 這個成功的扣下了ppt白板
srcPic = cv2.imread('2345.jpg')
length=srcPic.shape[0]
depth=srcPic.shape[1]
polyPic = srcPic
shrinkedPic = srcPic
greyPic = cv2.cvtColor(shrinkedPic,cv2.COLOR_BGR2GRAY)
ret,binPic = cv2.threshold(greyPic,130,255,cv2.THRESH_BINARY)
print(binPic.shape)
median = cv2.medianBlur(binPic,5)
# 進行邊緣檢測
cannyPic = cv2.Canny(median,10,200)

cv2.namedWindow("binary",0)
cv2.namedWindow("binary2",0)
cv2.imshow("binary",cannyPic)
# 找出輪廓
contours,hierarchy = cv2.findContours(cannyPic,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
cv2.imwrite('binary2.png',cannyPic)
cv2.imshow("binary2",cannyPic)
i = 0
maxArea = 0
# 挨個檢檢視那個輪廓面積最大
for i in range(len(contours)):
 if cv2.contourArea(contours[i]) > cv2.contourArea(contours[maxArea]):
 maxArea = i
#檢查輪廓得到分佈在四個角上的點
hull = cv2.convexHull(contours[maxArea])
s = [[1,2]]
z = [[2,3]]
for i in hull:
 s.append([i[0][0],i[0][1]])
 z.append([i[0][0],i[0][1]])
del s[0]
del z[0]

#現在的目標是從一堆點中挑出分佈在四個角落的點,決定把圖片分為四等份,每個區域的角度來劃分點,
#預設四個角分別分佈在影象的四等分的區間上,也就是矩形在影象中央
# 我們把所有點的座標,都減去圖片中央的那個點(當成原點),然後按照x y座標值的正負 判斷屬於哪一個區間

center=[length/2,depth/2]

# 可以得到小數
for i in range(len(s)):
 s[i][0] = s[i][0] - center[0]
 s[i][1] = s[i][1] - center[1]
one = []
two = []
three = []
four = []
# 判斷是那個區間的
for i in range(len(z)):
 if s[i][0] <= 0 and s[i][1] <0 :
 one.append(i)
 elif s[i][0] > 0 and s[i][1] <0 :
 two.append(i)
 elif s[i][0] >= 0 and s[i][1] > 0:
 four.append(i)
 else:three.append(i)

p=[]
distance=0
temp = 0
# 下面開始判斷每個區間的極值,要選擇距離中心點最遠的點,就是角點
for i in one :
 x=z[i][0]-center[0]
 y=z[i][1]-center[1]
 d=x*x+y*y
 if d > distance :
 temp = i
 distance = d
p.append([z[temp][0],z[temp][1]])
distance=0
temp=0
for i in two :
 x=z[i][0]-center[0]
 y=z[i][1]-center[1]
 d=x*x+y*y
 if d > distance :
 temp = i
 distance = d
p.append([z[temp][0],z[temp][1]])
distance=0
temp=0
for i in three :
 x=z[i][0]-center[0]
 y=z[i][1]-center[1]
 d=x*x+y*y
 if d > distance :
 temp = i
 distance = d
p.append([z[temp][0],z[temp][1]])
distance=0
temp=0
for i in four :
 x=z[i][0]-center[0]
 y=z[i][1]-center[1]
 d=x*x+y*y
 if d > distance :
 temp = i
 distance = d
p.append([z[temp][0],z[temp][1]])


for i in p:
 cv2.circle(polyPic,(i[0],i[1]),2,(0,0),2)
# 給四個點排一下順序
a=[]
b=[]
st=[]
for i in p:
 a.append(i[0])
 b.append(i[1])
index=np.lexsort((b,a))
for i in index:
 st.append(p[i])
p = st
print(p)
pts1 = np.float32([[p[0][0],p[0][1]],[p[1][0],p[1][1]],[p[2][0],p[2][1]],[p[3][0],p[3][1]]])
# dst=np.float32([[0,0],[0,srcPic.shape[1]],[srcPic.shape[0],srcPic.shape[1]]])
dst=np.float32([[0,600],[400,600]])

# 投影變換
M = cv2.getPerspectiveTransform(pts1,dst)
cv2.namedWindow("srcPic2",0)
cv2.imshow("srcPic2",srcPic)
#dstImage = cv2.warpPerspective(srcPic,M,(srcPic.shape[0],srcPic.shape[1]))
dstImage = cv2.warpPerspective(srcPic,(400,600))


# 在原圖上畫出紅色的檢測痕跡,先生成一個黑色圖
black = np.zeros((shrinkedPic.shape[0],shrinkedPic.shape[1]),dtype=np.uint8)
# 二值圖轉為三通道圖
black3 = cv2.merge([black,black,black])
# black=black2
cv2.drawContours(black,contours,maxArea,11)
cv2.drawContours(black3,(255,11)
cv2.imwrite('cv.png',black)

cv2.namedWindow("cannyPic",0)
cv2.imshow("cannyPic",black)
cv2.namedWindow("shrinkedPic",0)
cv2.imshow("shrinkedPic",polyPic)
cv2.namedWindow("dstImage",0)
cv2.imshow("dstImage",dstImage)
# 等待一個按下鍵盤事件
cv2.waitKey(0)
# 銷燬所有創建出的視窗

執行效果

openCV提取影象中的矩形區域

用到的圖片

openCV提取影象中的矩形區域

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。