当前位置:网站首页>[opencv learning] [contour detection]
[opencv learning] [contour detection]
2022-07-02 12:52:00 【A sea of stars】
Today, learn the contour detection method
import cv2
import numpy as np
# Show the image , Encapsulate as a function
def cv_show_image(name, img):
cv2.imshow(name, img)
cv2.waitKey(0) # Waiting time , In milliseconds ,0 Represents any key termination
cv2.destroyAllWindows()
# Function of edge detection
# cv2.findContours(img, mode, method)
# img: The input image , For high accuracy , It is recommended to use binary image
# mode: RETR_EXTERNAL( Only the outer contour is detected )、
# RETR_LIST( Detect all contours and keep the results to a List in )
# RETR_CCOMP, Detect all contours , And wrap the results in two layers , The first layer is the external outline of each part , The second layer is the inner boundary of the cavity
# RETR_TREE, Detect all contours , And reconstruct the hierarchy of nested contours
# RETR_LIST From an explanatory point of view , This should be the simplest . It just extracts all the contours , Without creating any parent-child relationship .
# RETR_EXTERNAL If you choose this mode , Only the outermost outline will be returned , All sub contours are ignored .
# RETR_CCOMP In this mode, all contours will be returned and divided into two levels of organizational structure .
# RETR_TREE In this mode, all contours are returned , And create a complete list of organizational structures . It will even tell you who is Grandpa , Dad , son , Grandson, etc .
# methord: Method of contour detection
# CHAIN_APPROX_NONE: With freeman Chain code output outline ,
# CHAIN_APPROX_SIMPLE: Keep only the end part , That is, only the end points are saved for horizontal, vertical and inclined lines . Less and more concise data .
img = cv2.imread('images/contour.png') # Turn to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, threshold = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # Convert to binary image
cv_show_image('binary_src_img', threshold)
# contours, All contour information , It's a list structure
# hierarchy It's a hierarchy , It is also a structure that retains all results
contours, hierarchy = cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
print(len(contours))
print(type(contours))
draw_img = img.copy() # Copy an image , Keep the original image
# -1 It means that all the outlines are drawn , The last two parameters are the color and thickness of the outline ,drawContours It will be modified in place on the input image
res = cv2.drawContours(draw_img, contours, contourIdx=-1, color=(0, 255, 0), thickness=1)
cv_show_image('draw_contours_img', res)
# Features of contour
for i in range(len(contours)):
cont = contours[i]
print(' The first {} The area of the outline is {}, The circumference is {}', i, cv2.contourArea(cont), cv2.arcLength(cont, True)) # true Closed
# The outline is approximate
# There is a curve from point A point-to-point B, There is a connection AB, There is a point on the curve C,C The straight line AB Distance of d Maximum . If d <= A certain threshold , Then we can use AB Straight lines directly replace curves AB
# If d > A certain threshold , So you can't use another curve AB Straight line substituted , Then at this time, we have to put the curve AB Continue to divide into two sections , They are curves AC Sum curve CB. Try further
# Try further , See if this curve can be straight AC And straight lines CB Instead of . This is a divide and conquer / Recursively solve .
draw_img = img.copy()
for i in range(len(contours)):
cont = contours[i]
epsilon = 0.03 * cv2.arcLength(cont, True)
approx = cv2.approxPolyDP(cont, epsilon, True) # Find the approximation of the contour ,True It means closed
# Draw an approximate outline , Pass it on to drawContours The contour type of must be list
draw_img = cv2.drawContours(draw_img, [approx], contourIdx=-1, color=(0, 255, 0), thickness=1)
cv_show_image('approx_contours_img', draw_img)
# Outer rectangle
draw_img = img.copy()
for i in range(len(contours)):
cont = contours[i]
x,y,w,h = cv2.boundingRect(cont) # According to the contour, calculate the rectangular coordinates with the farthest circumscribed .
draw_img = cv2.rectangle(draw_img, pt1=(x,y), pt2=(x+w, y+h), color=(0, 255, 0), thickness=2) # Draw this rectangle , Will draw on the original picture
cv_show_image('rectangle_contours_img', draw_img)
# Circumcircle
draw_img = img.copy()
for i in range(len(contours)):
cont = contours[i]
(x,y), radius = cv2.minEnclosingCircle(cont) # Calculate the center and radius of the outermost circle according to the contour .
center = (int(x), int(y))
radius = int(radius)
draw_img = cv2.circle(draw_img, center=center, radius=radius, color=(0, 255, 0), thickness=2) # Draw this rectangle , Will draw on the original picture
cv_show_image('circle_contours_img', draw_img)
The original image is as follows :
Draw all the outlines :
The outline has internal outline and external outline , If you use mode = RETR_EXTERNAL Can only draw the outline 
Draw all approximate outlines :
Draw the circumscribed largest rectangle of all contours

Draw the circumscribed maximum circle of all contours

边栏推荐
- Win10 system OmniPeek wireless packet capturing network card driver failed to install due to digital signature problem solution
- JS8day(滚动事件(scroll家族),offset家族,client家族,轮播图案例(待做))
- Js1day (syntaxe d'entrée / sortie, type de données, conversion de type de données, Var et let différenciés)
- moon
- 软件测试面试题-2022年大厂面试题合集
- Js3day (array operation, JS bubble sort, function, debug window, scope and scope chain, anonymous function, object, Math object)
- 应用LNK306GN-TL 转换器、非隔离电源
- Ntmfs4c05nt1g N-ch 30V 11.9a MOS tube, pdf
- The coloring method determines the bipartite graph acwing 860 Chromatic judgement bipartite graph
- What is the relationship between NFT and metauniverse? How to view the market? The future market trend of NFT
猜你喜欢

Efficiency comparison between ArrayList and LinkedList

线性DP AcWing 896. 最长上升子序列 II

spfa AcWing 852. spfa判断负环

C#运算符

Variable, "+" sign, data type

Js1day (syntaxe d'entrée / sortie, type de données, conversion de type de données, Var et let différenciés)

Linear DP acwing 896 Longest ascending subsequence II

Hash table acwing 840 Simulated hash table

应用LNK306GN-TL 转换器、非隔离电源

Heap acwing 838 Heap sort
随机推荐
js1day(輸入輸出語法,數據類型,數據類型轉換,var和let區別)
区间DP AcWing 282. 石子合并
JS10day(api 阶段性完结,正则表达式简介,自定义属性,过滤敏感词案例,注册模块验证案例)
模块化 CommonJS ES Module
Browser storage scheme
Linear DP acwing 899 Edit distance
堆 AcWing 838. 堆排序
Async/await asynchronous function
百款拿来就能用的网页特效,不来看看吗?
The coloring method determines the bipartite graph acwing 860 Chromatic judgement bipartite graph
Sensor adxl335bcpz-rl7 3-axis accelerometer complies with rohs/weee
ArrayList与LinkedList效率的对比
Redis transaction mechanism implementation process and principle, and use transaction mechanism to prevent inventory oversold
Heap acwing 838 Heap sort
8 examples of using date commands
VLAN experiment
Modular commonjs es module
堆 AcWing 839. 模拟堆
Hash table acwing 841 String hash
. Net, C # basic knowledge