openCV提取圖像中的矩形區(qū)域
改編自詳解利用OpenCV提取圖像中的矩形區(qū)域(PPT屏幕等) 原文是c++版,我改成了python版,供大家參考學(xué)習(xí)。
主要思想:邊緣檢測(cè)—》輪廓檢測(cè)—》找出最大的面積的輪廓—》找出頂點(diǎn)—》投影變換
import numpy as np
import cv2
# 這個(gè)成功的扣下了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)
# 進(jìn)行邊緣檢測(cè)
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
# 挨個(gè)檢查看那個(gè)輪廓面積最大
for i in range(len(contours)):
if cv2.contourArea(contours[i]) > cv2.contourArea(contours[maxArea]):
maxArea = i
#檢查輪廓得到分布在四個(gè)角上的點(diǎn)
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]
#現(xiàn)在的目標(biāo)是從一堆點(diǎn)中挑出分布在四個(gè)角落的點(diǎn),決定把圖片分為四等份,每個(gè)區(qū)域的角度來劃分點(diǎn),
#默認(rèn)四個(gè)角分別分布在圖像的四等分的區(qū)間上,也就是矩形在圖像中央
# 我們把所有點(diǎn)的坐標(biāo),都減去圖片中央的那個(gè)點(diǎn)(當(dāng)成原點(diǎn)),然后按照x y坐標(biāo)值的正負(fù) 判斷屬于哪一個(gè)區(qū)間
center=[length/2,depth/2]
# 可以得到小數(shù)
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 = []
# 判斷是那個(gè)區(qū)間的
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
# 下面開始判斷每個(gè)區(qū)間的極值,要選擇距離中心點(diǎn)最遠(yuǎn)的點(diǎn),就是角點(diǎn)
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,255,0),2)
# 給四個(gè)點(diǎn)排一下順序
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],0],[srcPic.shape[0],srcPic.shape[1]]])
dst=np.float32([[0,0],[0,600],[400,0],[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,M,(400,600))
# 在原圖上畫出紅色的檢測(cè)痕跡,先生成一個(gè)黑色圖
black = np.zeros((shrinkedPic.shape[0], shrinkedPic.shape[1]), dtype=np.uint8)
# 二值圖轉(zhuǎn)為三通道圖
black3 = cv2.merge([black, black, black])
# black=black2
cv2.drawContours(black, contours, maxArea, 255, 11)
cv2.drawContours(black3, contours, maxArea, (255, 0, 0), 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)
# 等待一個(gè)按下鍵盤事件
cv2.waitKey(0)
# 銷毀所有創(chuàng)建出的窗口
運(yùn)行效果

用到的圖片

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
深入了解python基于tkinter寫的畫圖項(xiàng)目
這篇文章主要為大家介紹了python基于tkinter寫的畫圖項(xiàng)目,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2021-12-12
Python實(shí)戰(zhàn)之單詞打卡統(tǒng)計(jì)
這篇文章主要介紹了Python實(shí)戰(zhàn)之單詞打卡統(tǒng)計(jì),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)python的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04
Python中schedule模塊定時(shí)任務(wù)的使用方法(2)
這篇文章主要介紹了Python中schedule模塊定時(shí)任務(wù)的使用方法,文章基于上一篇文章的內(nèi)容展開的后續(xù),需要的朋友可以參考一下2022-05-05
python configparser中默認(rèn)值的設(shè)定方式
這篇文章主要介紹了python configparser中默認(rèn)值的設(shè)定方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
使用python實(shí)現(xiàn)對(duì)元素的長(zhǎng)截圖功能
這篇文章主要介紹了用python實(shí)現(xiàn)對(duì)元素的長(zhǎng)截圖功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2019-11-11
Python內(nèi)置方法實(shí)現(xiàn)字符串的秘鑰加解密(推薦)
在Python中實(shí)現(xiàn)AES算法需要借助的第三方庫Crypto,其在各個(gè)操作系統(tǒng)上的安裝方法有些許復(fù)雜,所以對(duì)于簡(jiǎn)單的使用有點(diǎn)殺雞用牛刀的意思。這篇文章主要介紹了利用Python內(nèi)置方法實(shí)現(xiàn)字符串的秘鑰加解密,需要的朋友可以參考下2019-12-12
Python的flask接收前臺(tái)的ajax的post數(shù)據(jù)和get數(shù)據(jù)的方法
這篇文章主要介紹了Python的flask接收前臺(tái)的ajax的post數(shù)據(jù)和get數(shù)據(jù)的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04

