python 生成任意形狀的凸包圖代碼
一、效果圖:
在左圖的白色區(qū)域周圍,畫任意形狀的凸包圖。

二、代碼
import cv2
import numpy as np
def generate_poly(image, n, area_thresh):
"""
隨機(jī)生成凸包
:param image: 二值圖
:param n: 頂點(diǎn)個(gè)數(shù)
:param area_thresh: 刪除小于此面積閾值的凸包
:return: 凸包圖
"""
row, col = np.where(image[:, :, 0] == 255) # 行,列
point_set = np.zeros((n, 1, 2), dtype=int)
for j in range(n):
index = np.random.randint(0, len(row))
point_set[j, 0, 0] = col[index]
point_set[j, 0, 1] = row[index]
hull = []
hull.append(cv2.convexHull(point_set, False))
drawing_board = np.zeros(image.shape, dtype=np.uint8)
cv2.drawContours(drawing_board, hull, -1, (255, 255, 255), -1)
cv2.namedWindow('drawing_board', 0), cv2.imshow('drawing_board', drawing_board), cv2.waitKey()
# 如果生成面積過小,重新生成
if cv2.contourArea(hull[0]) < area_thresh:
drawing_board = generate_poly(image, n, area_thresh)
# 如果生成洞,重新生成
is_hole = image[drawing_board == 255] == 255
if is_hole.all() == True: # 洞,則drawing_board所有為255的地方,image也是255,all()即為所有位置
drawing_board = generate_poly(image, n, area_thresh)
return drawing_board
img = np.zeros((256, 256, 3), np.uint8)
cv2.circle(img, (100, 100), 50, (255, 255, 255), -1)
cv2.namedWindow('img', 0), cv2.imshow('img', img), cv2.waitKey()
img_hull = generate_poly(img, 8, 100)
cv2.namedWindow('img_hull', 0), cv2.imshow('img_hull', img_hull), cv2.waitKey()
補(bǔ)充知識(shí):opencv python 輪廓特征/凸包/外接矩形/外接圓/擬合矩形/擬合直線/擬合圓
1 圖像的矩
cv2.moments()
圖像的矩可以幫助計(jì)算物體的某些特征,如對(duì)象的質(zhì)心,對(duì)象的區(qū)域等.
代碼:
import cv2
import numpy as np
img = cv2.imread('img7.png',0)
ret,thresh = cv2.threshold(img,127,255,0)
im2,contours,hierarchy = cv2.findContours(thresh, 1, 2)
cnt = contours[0]
M = cv2.moments(cnt)
print( M )
輸出:
{'m00': 283.0, 'm10': 8260.666666666666, 'm01': 34747.666666666664, 'm20': 251349.8333333333, 'm11': 1008063.0, 'm02': 4274513.166666666, 'm30': 7941981.4, 'm21': 30484543.9, 'm12': 123258620.46666667, 'm03': 526819846.70000005, 'mu20': 10223.989595602674, 'mu11': -6208.702394974302, 'mu02': 8080.874165684916, 'mu30': 8302.495426246896, 'mu21': -14552.154961312423, 'mu12': 11791.528133469663, 'mu03': -3268.923251092434, 'nu20': 0.12765785058625623, 'nu11': -0.07752253611575, 'nu02': 0.10089867729257346, 'nu30': 0.006162296011483629, 'nu21': -0.010800931752771139, 'nu12': 0.008751933371317017, 'nu03': -0.0024262672459139235}
此刻,可以提取有用的數(shù)據(jù),如面積,質(zhì)心等.
質(zhì)心由關(guān)系給出:
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
2輪廓面積
cv2.contourArea(contour[, oriented])
3輪廓周長
cv2.arcLength(curve, closed)
第二個(gè)參數(shù)指定形狀是否為閉合輪廓
4輪廓近似
它根據(jù)我們指定的精度將輪廓形狀近似為具有較少頂點(diǎn)數(shù)的另一個(gè)形狀.它是Douglas-Peucker算法的一種實(shí)現(xiàn)方式.
cv2.approxPolyDP(curve, epsilon, closed[, approxCurve])
第二個(gè)參數(shù)epsilon,它是從輪廓到近似輪廓的最大距離.第三個(gè)參數(shù)指定曲線是否閉合.
下面,在第二幅圖像中,綠線表示epsilon =弧長的10%的近似曲線. 第三幅圖像顯示相同的epsilon =弧長的1%.
代碼:
import cv2
import numpy as np
img = cv2.imread('img8.png')
cv2.imshow('src',img)
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[1]
epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
cv2.polylines(img, [approx], True, (0, 0, 255), 2)
cv2.imshow('show',img)
cv2.waitKey()

5凸包
凸包看起來類似輪廓近似,但是它不是(兩者在某些情況下可能提供相同的結(jié)果).
convexHull(points[, hull[, clockwise[, returnPoints]]]):檢查曲線的凸性缺陷并進(jìn)行修正.
points:傳入的輪廓
hull:輸出
clockwise:方向標(biāo)志,如果為True,則順時(shí)針方向輸出凸包.
returnPoints:默認(rèn)情況下為True,然后它返回hull points的坐標(biāo); 如果為False,則返回與hull points對(duì)應(yīng)的輪廓點(diǎn)的索引
下面的手形圖像. 紅線表示手的凸包, 雙面箭頭標(biāo)記顯示凸起缺陷.

代碼:
import cv2
import numpy as np
img = cv2.imread('img8.png')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[1]
hull = cv2.convexHull(cnt)
returnPoints = True,得到以下值:
array([[[192, 135]], [[ 9, 135]], [[ 9, 12]], [[192, 12]]], dtype=int32)
如果想找到凸性缺陷,需要傳遞returnPoints = False,得到以下結(jié)果:
array([[129], [ 67], [ 0], [142]], dtype=int32)
這些是輪廓中相應(yīng)點(diǎn)的索引,檢查第一個(gè)值:
cnt[129]
Out[3]: array([[192, 135]], dtype=int32)
與第一個(gè)結(jié)果相同.
6 檢查凸性
cv2.isContourConvex(contour):檢查曲線是否凸起
7 外接矩形
7.1 直邊外接矩形
它是一個(gè)直的矩形,它不考慮對(duì)象的旋轉(zhuǎn)。因此,邊界矩形的面積不會(huì)最小.
cv.boundingRect()
設(shè)(x,y)為矩形的左上角坐標(biāo),(w,h)為寬度和高度
代碼:
import cv2
import numpy as np
img = cv2.imread('img7.png')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('show',img)
cv2.waitKey()

7.2 最小外接矩形
cv.minAreaRect返回一個(gè)Box2D結(jié)構(gòu),其中包含以下detals - (center(x,y),(width,height),rotation of rotation)
cv.boxPoints畫上述矩形.
代碼:
rect = cv2.minAreaRect(cnt) box = cv2.boxPoints(rect) box = np.int0(box) cv2.drawContours(img,[box],0,(0,0,255),2)

8 最小封閉圈
(x,y),radius = cv2.minEnclosingCircle(cnt) center = (int(x),int(y)) radius = int(radius) cv2.circle(img,center,radius,(0,255,0),2)

9 擬合橢圓
ellipse = cv2.fitEllipse(cnt)
cv2.ellipse(img,ellipse,(0,255,0),2)

10 擬合直線
rows,cols = img.shape[:2] [vx,vy,x,y] = cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01) lefty = int((-x*vy/vx) + y) righty = int(((cols-x)*vy/vx)+y) cv2.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)

以上這篇python 生成任意形狀的凸包圖代碼就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python使用Keras庫中的LSTM模型生成新文本內(nèi)容教程
Python語言使用金庸小說文本庫,對(duì)文本進(jìn)行預(yù)處理,然后使用Keras庫中的LSTM模型創(chuàng)建和訓(xùn)練了模型,根據(jù)這個(gè)模型,我們可以生成新的文本,并探索小說的不同應(yīng)用2024-01-01
Python動(dòng)態(tài)配置管理Dynaconf的實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了Python動(dòng)態(tài)配置管理Dynaconf實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
用Python編寫一個(gè)基于終端的實(shí)現(xiàn)翻譯的腳本
這篇文章主要介紹了用Python編寫一個(gè)基于終端的實(shí)現(xiàn)翻譯的腳本,代碼基于Python2.x,需要的朋友可以參考下2015-04-04
五分鐘學(xué)會(huì)怎么用python做一個(gè)簡單的貪吃蛇
這篇文章主要介紹了五分鐘學(xué)會(huì)怎么用python做一個(gè)簡單的貪吃蛇,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2021-01-01
Python報(bào)錯(cuò)no?module?named?torch的幾種原因及解決方案
這篇文章主要給大家介紹了關(guān)于Python報(bào)錯(cuò)no?module?named?torch的幾種原因及解決方案,這是小白時(shí)常犯的錯(cuò),這個(gè)報(bào)錯(cuò)一般說明在你電腦當(dāng)前環(huán)境下沒有安裝torch這個(gè)模塊,但也有其他情況,需要的朋友可以參考下2023-10-10
用python實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了用python實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
win7 下搭建sublime的python開發(fā)環(huán)境的配置方法
Sublime Text具有漂亮的用戶界面和強(qiáng)大的功能,例如代碼縮略圖,Python的插件,代碼段等。還可自定義鍵綁定,菜單和工具欄。Sublime Text的主要功能包括:拼寫檢查,書簽,完整的 Python API,Goto功能,即時(shí)項(xiàng)目切換,多選擇,多窗口等等。2014-06-06
python如何求100以內(nèi)的素?cái)?shù)
在本篇文章里小編給大家分享的是關(guān)于python如何求100以內(nèi)的素?cái)?shù)的方法實(shí)例,需要的朋友們可以學(xué)習(xí)下。2020-05-05

