<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
我們將以兩種方式來展示我們這個專案的效果。
下面這是視訊的實時檢測,我分別用了盒子和蓋子來檢測,按理來說效果不應該怎麼差的,但我實在沒有找到合適的背景與物體。且我的攝像頭使用的是外設,我不得不手持,所以存在一點點的抖動,但我可以保證,它是缺少了適合檢測物體與背景。
我使用手機拍了一張照片並經過了ps修改了背景,效果不錯。
本專案中,我將選用A4紙張為背景,找到放在該區域中物件的長、寬。列印出相關的數值。
所有的資源,你都可以在我的GitHub上找到,我將在末尾附上連結
在專案當中,我將引入utils,而utils是適用於在我們專案中所寫的的檔案。有了對它的理解能幫助我們更好的理解本專案,所以我覺得有必要在此敘述一番。
import cv2 import numpy as np def getContours(img, cThr=[100, 100], showCanny=False, minArea=1000, filter=0, draw=False): imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) imgBlur = cv2.GaussianBlur(imgGray, (5, 5), 1) imgCanny = cv2.Canny(imgBlur, cThr[0], cThr[1]) kernel = np.ones((5, 5)) imgDial = cv2.dilate(imgCanny, kernel, iterations=3) imgThre = cv2.erode(imgDial, kernel, iterations=2) if showCanny: cv2.imshow('Canny', imgThre) contours, hiearchy = cv2.findContours(imgThre, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) finalCountours = [] for i in contours: area = cv2.contourArea(i) if area > minArea: peri = cv2.arcLength(i, True) approx = cv2.approxPolyDP(i, 0.02 * peri, True) bbox = cv2.boundingRect(approx) if filter > 0: if len(approx) == filter: finalCountours.append([len(approx), area, approx, bbox, i]) else: finalCountours.append([len(approx), area, approx, bbox, i]) finalCountours = sorted(finalCountours, key=lambda x: x[1], reverse=True) if draw: for con in finalCountours: cv2.drawContours(img, con[4], -1, (0, 0, 255), 3) return img, finalCountours def reorder(myPoints): # print(myPoints.shape) myPointsNew = np.zeros_like(myPoints) myPoints = myPoints.reshape((4, 2)) add = myPoints.sum(1) myPointsNew[0] = myPoints[np.argmin(add)] myPointsNew[3] = myPoints[np.argmax(add)] diff = np.diff(myPoints, axis=1) myPointsNew[1] = myPoints[np.argmin(diff)] myPointsNew[2] = myPoints[np.argmax(diff)] return myPointsNew def warpImg(img, points, w, h, pad=20): # print(points) points = reorder(points) pts1 = np.float32(points) pts2 = np.float32([[0, 0], [w, 0], [0, h], [w, h]]) matrix = cv2.getPerspectiveTransform(pts1, pts2) imgWarp = cv2.warpPerspective(img, matrix, (w, h)) imgWarp = imgWarp[pad:imgWarp.shape[0] - pad, pad:imgWarp.shape[1] - pad] return imgWarp def findDis(pts1, pts2): return ((pts2[0] - pts1[0]) ** 2 + (pts2[1] - pts1[1]) ** 2) ** 0.5
接下來,我將按照慣例講解,我們就以每個函數的意義來講。
1.getContours()函數,曾在我以前的部落格中出現過。正如它的命名,我們是為了得到輪廓。將原始影象依次經過這些轉化:灰度影象、高斯模糊、canny檢測邊緣、膨脹、侵蝕等。 cv2.findContours()從影象ROI中提取輪廓,然後在整個影象上下文中分析輪廓,引數cv2.RETR_EXTERNAL將會獲取外部邊緣;
cv2.contourArea()計算輪廓面積;
cv2.contourArea()計算輪廓周長或曲線長度;
cv2.approxPolyDP()以指定精度近似多邊形曲線;
cv2.boundingRect()函數計算並返回指定點集或灰度影象非零畫素的最小右上邊界矩形;
之後用finalCountours這個空列表來接受我們需要用到的資訊,再對其輪廓的大小進行排序,因為我們需要的是最大的邊界框。
cv2.drawContours()繪製輪廓輪廓或填充輪廓,最後返回img, finalCountours。
2.reorder函數,myPointsNew = np.zeros_like(myPoints),返回與myPoints具有相同形狀和型別的零陣列,在列印了myPoints.shape,它所返回的值是(4,1,2),不難理解,4指的是四個點,2指的是x,y,我們不需要中間的1,所以要對其進行重塑。np.argmin返回沿軸的最小值的索引,np.argmax返回沿軸的最大值的索引。所以此函數的作用是將順序改為最下面的順序。
4.warpImg()函數,其實就是透視變換,詳細的函數可以回頭複習一下Opencv的檔案,我在此不做多的講述。
5.findDis()函數我們用一張圖來解釋,個人手繪:
import cv2 import utils ################################### webcam = False path = '1.png' cap = cv2.VideoCapture(1) cap.set(10, 160) cap.set(3, 1920) cap.set(4, 1080) scale = 3 wP = 210 * scale hP = 297 * scale ################################### while True: if webcam: success, img = cap.read() else: img = cv2.imread(path) imgContours, conts = utils.getContours(img, minArea=50000, filter=4) if len(conts) != 0: biggest = conts[0][2] # print(biggest) imgWarp = utils.warpImg(img, biggest, wP, hP) imgContours2, conts2 = utils.getContours(imgWarp, minArea=2000, filter=4, cThr=[50, 50], draw=False) if len(conts) != 0: for obj in conts2: cv2.polylines(imgContours2, [obj[2]], True, (0, 255, 0), 2) nPoints = utils.reorder(obj[2]) nW = round((utils.findDis(nPoints[0][0] // scale, nPoints[1][0] // scale) / 10), 1) nH = round((utils.findDis(nPoints[0][0] // scale, nPoints[2][0] // scale) / 10), 1) cv2.arrowedLine(imgContours2, (nPoints[0][0][0], nPoints[0][0][1]), (nPoints[1][0][0], nPoints[1][0][1]), (255, 0, 255), 3, 8, 0, 0.05) cv2.arrowedLine(imgContours2, (nPoints[0][0][0], nPoints[0][0][1]), (nPoints[2][0][0], nPoints[2][0][1]), (255, 0, 255), 3, 8, 0, 0.05) x, y, w, h = obj[3] cv2.putText(imgContours2, '{}cm'.format(nW), (x + 30, y - 10), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1.5, (255, 0, 255), 2) cv2.putText(imgContours2, '{}cm'.format(nH), (x - 70, y + h // 2), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1.5, (255, 0, 255), 2) cv2.imshow('A4', imgContours2) img = cv2.resize(img, (0, 0), None, 0.5, 0.5) cv2.imshow('Original', img) if cv2.waitKey(1) & 0xFF ==27: break
那麼,本專案的程式碼我看了一下,將utils.py檔案看懂之後,不難理解,所以本專案我就不仔細講解了。
本專案主要是運用了之前掃描檔案的思想,以A4紙為背景,檢測其中區域的物體長和寬。我的攝像頭無法固定,所以是手持的,且由於我在寢室裡面是真的沒有找到合適的測量物體以及背景色(全是米色或原木色的)。所以效果有所欠缺,但經過ps修改的圖片,檢測的效果還是很不錯的。
以上就是Python+Opencv實現物體尺寸測量的方法詳解的詳細內容,更多關於Python Opencv物體尺寸測量的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45