Python基于opencv的簡單圖像輪廓形狀識別(全網(wǎng)最簡單最少代碼)
可以直接跳到最后整體代碼看一看是不是很少的代碼?。。。?br />
思路:
1. 數(shù)據(jù)的整合
2. 圖片的灰度轉(zhuǎn)化
3. 圖片的二值轉(zhuǎn)化
4. 圖片的輪廓識別
5. 得到圖片的頂點數(shù)
6. 依據(jù)頂點數(shù)判斷圖像形狀
一、原數(shù)據(jù)的展示
圖片文件共36個文件夾,每個文件夾有100張圖片,共3600張圖片。
每一個文件夾里都有形同此類的圖形
二、數(shù)據(jù)的整合
對于多個文件夾,分析起來很不方便,所有決定將其都放在一個文件夾下進行分析,在python中具體實現(xiàn)如下:
本次需要的包
import cv2 import os from PIL import Image import matplotlib.pyplot as plt import numpy as np
a=os.listdir('C:\\Users\\dell\\Desktop\\OpenCVProofSet')#循環(huán)讀取每個子文件夾 for i in range(len(a)): b=os.listdir('C:\\Users\\dell\\Desktop\\OpenCVProofSet\\'+a[i])#讀取每個子文件下的圖片文件 for j in range(len(b)): c=Image.open('C:\\Users\\dell\\Desktop\\OpenCVProofSet\\'+a[i]+'\\'+b[j])#循環(huán)讀取每個圖片文件 c.save('C:\\Users\\dell\\Desktop\\cleardata\\'+str(i)+'_'+str(j)+'.png')#以文件夾序號和圖片序號為名保存在一個興建文件夾下
結(jié)果如下:
三、圖片輪廓的確定
3.1圖片的灰度處理
以下以一張圖片為例子作為說明
對于灰度的處理,選擇使用opencv的cv2.cvtColor函數(shù),代碼示例如下:
d=os.listdir('C:\\Users\\dell\\Desktop\\cleardata\\')#文件路徑 e=cv2.imread('C:\\Users\\dell\\Desktop\\cleardata\\'+d[5])#以矩陣的形式圖片讀入 plt.imshow(e)#畫出示例圖
進行灰度的轉(zhuǎn)化:
g=cv2.cvtColor(e,cv2.COLOR_BGR2GRAY)##灰度轉(zhuǎn)化
3.2圖片的二值轉(zhuǎn)化
對于圖片的二值轉(zhuǎn)化這里選用cv2.threshold函數(shù),代碼示例如下:
r,b=cv2.threshold(g,0,255,cv2.THRESH_OTSU)#二值轉(zhuǎn)化,大于0的像素統(tǒng)一設(shè)置為255,小于等于0的統(tǒng)一設(shè)置為0
上述代碼的第一個參數(shù)為灰度圖形,第二個參數(shù)是閾值,即大于0的像素點轉(zhuǎn)化為255,然后選用的THRESH_OTSU方法,具體說明如下:
通常情況,我們一般不知道設(shè)定怎樣的閾值thresh才能得到比較好的二值化效果,只能去試。如對于一幅雙峰圖像(理解為圖像直方圖中存在兩個峰),我們指定的閾值應(yīng)盡量在兩個峰之間的峰谷。這時,就可以用第四個參數(shù)THRESH_OTSU,它對一幅雙峰圖像自動根據(jù)其直方圖計算出合適的閾值(對于非雙峰圖,這種方法得到的結(jié)果可能不理想)。
對于雙峰圖,我們需要多傳入一個參數(shù)cv2.THRESH_OTSU,并且把閾值thresh設(shè)為0,算法會找到最優(yōu)閾值,并作為第一個返回值ret返回。
其中會返回兩個值,第二個值就是二值化后的圖形矩陣。
3.3輪廓的尋找
在輪廓的尋找方面,采用cv2.findContours方式。代碼示例如下:
cr,t=cv2.findContours(b, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)##找到邊界,第一個參數(shù)是二值圖像,第二個參數(shù)是獲取輪廓的方式, #第三個參數(shù)定義輪廓的近似方式
上述函數(shù)里的參數(shù)中,第一個參數(shù)是二值化后的矩陣,第二個參數(shù)是獲取輪廓的方式,第三個參數(shù)是定義輪廓的近似方式。后面兩個參數(shù)的具體解釋如下:
上面得到的結(jié)果中第一個結(jié)果是輪廓點的集合。
畫出邊界輪廓,運用函數(shù)是cv2.drawContours,代碼示例如下:
plt.imshow(cv2.drawContours(e,cr,-1,50))#畫出邊界,可以看出有坐標軸和五角星兩個邊界,第一個參數(shù)是原圖,第二個參數(shù)是邊界, #第三個參數(shù)代表畫出所有邊界,第四個參數(shù)是線的粗細
上述函數(shù)中第一個參數(shù)是原始圖形,第二個參數(shù)是得到的輪廓點的集合,第三個參數(shù)是代表畫出所有輪廓點,第四個參數(shù)是線的粗細。
得到結(jié)果如下:
可以發(fā)現(xiàn),坐標軸的輪廓和五角星的輪廓都被畫了出來。
3.4輪廓的逼近,得到頂點
在得到輪廓點后,需要得到輪廓的頂點,通過頂點得到具體什么圖形,在輪廓逼近中用到兩個函數(shù):cv2.arcLength,cv2.approxPolyDP,代碼示例如下:
ep = 0.01*cv2.arcLength(cr[1], True)#五角星輪廓的周長cr[0]是坐標軸的周長,然后將其縮小,作為下一步的閾值 ap = cv2.approxPolyDP(cr[1], ep, True)#輪廓的轉(zhuǎn)折點的近似點
cv2.arcLength得到的是輪廓點形成的曲線圍成的圖形的周長,cr[1]代表里層五角星的輪廓點,因為cr里有兩個輪廓集合,一個是外層的坐標軸的輪廓點集合,一個是里層五角星的輪廓點集合。True代表閉合的曲線。將其取1%作為下一個函數(shù)的閾值。
cv2.approxPolyDP將其得到的輪廓點進行篩選(按設(shè)定的閾值與其真實的線進行比較),其篩選的標準就是上一個函數(shù)得到的1%的周長,大于這個值的點舍去,小于這個值的點保留,True依然代表閉合曲線。
通過以上的步驟就可以保留一些點,而這些點就是得到頂點(這點需要讀者去想一想,為什么以1%周長為閾值得到的點就是頂點,作者認為是兩條線的拐點相對于來說是里真實線最近的點)
頂點數(shù):
len(ap)#可以看見五角星有10個點
四、依據(jù)頂點判斷形狀
根據(jù)得到的定點數(shù)就可判斷出形狀了,三個頂點就是三角形,四個就是矩形,十個就是五角星,十個以上就是圓形了;上述的完整代碼如下:
import cv2 import os from PIL import Image import matplotlib.pyplot as plt import numpy as np d=os.listdir('C:\\Users\\dell\\Desktop\\cleardata\\') for i in range(len(d)): e=cv2.imread('C:\\Users\\dell\\Desktop\\cleardata\\'+d[i]) g=cv2.cvtColor(e,cv2.COLOR_BGR2GRAY) r,b=cv2.threshold(g,0,255,cv2.THRESH_OTSU) cr,t=cv2.findContours(b, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) ep = 0.01*cv2.arcLength(cr[1], True) ap = cv2.approxPolyDP(cr[1], ep, True) co=len(ap) if co==3: st='三角形' elif co==4: st='矩形' elif co==10: st='五角星' else: st='圓' plt.imsave('C:\\Users\\dell\\Desktop\\形狀\\'+st+str(e[100][100])+str(i)+'.jpg',e)#取圖像中間的點的RGB作為顏色代表
這里我還取了圖形的中點,希望得到圖片的顏色,其得到的是RGB值,通過RGB值就可以得到顏色。
最終結(jié)果如下:
到此這篇關(guān)于基于opencv的簡單圖像輪廓形狀識別(全網(wǎng)最簡單最少代碼)的文章就介紹到這了,更多相關(guān)opencv 圖像輪廓形狀識別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python使用Tkinter顯示網(wǎng)絡(luò)圖片的方法
這篇文章主要介紹了python使用Tkinter顯示網(wǎng)絡(luò)圖片的方法,涉及Python操作圖片的相關(guān)技巧,需要的朋友可以參考下2015-04-04python實現(xiàn)的MySQL增刪改查操作實例小結(jié)
這篇文章主要介紹了python實現(xiàn)的MySQL增刪改查操作,結(jié)合實例形式總結(jié)分析了Python基本的mysql增刪改查及銀行賬號查詢等相關(guān)操作實現(xiàn)技巧,需要的朋友可以參考下2018-12-12Python Paramiko實現(xiàn)SSHv2協(xié)議輕松管理遠程服務(wù)器
這篇文章主要為大家介紹了Python Paramiko實現(xiàn)SSHv2協(xié)議輕松管理遠程服務(wù)器,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01Python數(shù)據(jù)處理利器Slice函數(shù)用法詳解
這篇文章主要給大家介紹了關(guān)于Python數(shù)據(jù)處理利器Slice函數(shù)用法的相關(guān)資料,slice函數(shù)是Python中的一個內(nèi)置函數(shù),用于對序列進行切片操作,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-03-03Python利用pdfplumber庫提取pdf中表格數(shù)據(jù)
pdfplumber是一個用于從PDF文檔中提取文本和表格數(shù)據(jù)的Python庫,它可以幫助用戶輕松地從PDF文件中提取有用的信息,例如表格、文本、元數(shù)據(jù)等,本文介紹了如何通過Python的pdfplumber庫提取pdf中表格數(shù)據(jù),感興趣的同學(xué)可以參考一下2023-05-05