SoFunction
Updated on 2024-10-30

How to Extract Object Contours Using Python OpenCV Details

Usually when extracting the contour of an object, the image is noisy and the extraction result is not ideal. For example, when extracting the contour of the following figure

Extract code:

import cv2
 
img = ("")
("origin",img)
gray = (img,cv2.COLOR_BGR2GRAY)
ret,binary = (gray,128,255,cv2.THRESH_BINARY)
("binary",binary)
 
contours, hierarchy = (binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
(img,contours,-1,(0,0,255),3)
("result", img)
(0)

Extraction effects:

It can be seen that there is a very serious noise interference. Therefore, the interference of noise needs to be filtered before extracting the contours.

First, a mean filtering (low-pass filtering) of the image is performed to remove the noise

blured = (img,(5,5))
("blur",blured)

 

Use floodfill to remove the background around the target, the floodfill class started with ps's magic wand tool and is used here to remove the background.

mask = ((h+2, w+2), np.uint8)       # The mask length and width are both two pixels longer and wider than the input image, and the flood fill does not extend beyond the non-zero edge of the mask
#Flood filling is performed
(blured, mask, (10,10), (255,255,255), (2,2,2),(3,3,3),8)
("floodfill", blured)

Explanation of floodFill function

  • img: is the image to be flooded using the flooding algorithm
  • mask: for the mask layer, the use of masks can be specified in which region to use the algorithm, if it is for the complete image are to be used, the mask layer size of the original image rows + 2, the number of columns + 2. is a two-dimensional 0 matrix, the edge of the circle will be in the use of the algorithm is set to 1. And only for the mask layer corresponds to the position of the 0 can be flooded, so the mask layer initialized to the 0 moment. [dtype:np.uint8].
  • seed: the seed point for the flooding algorithm, also based on the pixel judgment of the point to decide and its similar color pixel points, whether to be flooded.
  • newvalue: is the newly assigned value for the flooded area (B,G,R)
  • (loDiff1,loDiff2,loDiff3): is the pixel value that can be downward relative to the seed seed point pixel, i.e., seed(B0,G0,R0), and the lower bound of the flooding region is (B0-loDiff1,G0-loDiff2,R0-loDiff3)
  • (upDiff1,upDiff2,upDiff3): is the pixel value that can be upward relative to the seed seed point pixel, i.e., seed(B0,G0,R0), the upper boundary of the flooding region is (B0+upDiff1,G0+upDiff2,R0+upDiff3)
  • flag: is the processing mode of the flooding algorithm:
  • Lower eight bits Controls the connectivity of the algorithm, which is centered on the SEED point, followed by judging several pixel points around it, and then taking into account several pixel points around the pixel point in the flooded area. Typically 4, 8; default is 4
  • The middle eight bits are closely related to the mask layer assignment, generally use (255<<8) to make the middle eight bits all bits 1, the value is 255, that is, the mask layer corresponds to the original flooding region of the part of the original map was assigned by the original initial value of 0 to 255, if the middle eight bits of 0, then the value is assigned to 1.
  • Higher octet Specified by opencv macro parameter
    • cv2.FLOODFILL_FIXED_RANGE: change image, fill newvalue
    • cv2.FLOODFILL_MASK_ONLY: does not change the original image, i.e. the newvalue parameter loses its effect, but changes the mask of the corresponding region to the value of the middle eight bits.

Then convert to grayscale

 gray = (blured,cv2.COLOR_BGR2GRAY)  
 ("gray", gray)  

At this time, the target image is surrounded by write unsmooth and some noise, so open and close operations are performed to get a smoother target

 # Define structure elements
 kernel = (cv2.MORPH_RECT,(50, 50))
 # Open and close operations, first open operation to remove background noise, then continue closed operation to fill the holes in the target
 opened = (gray, cv2.MORPH_OPEN, kernel)  
 closed = (opened, cv2.MORPH_CLOSE, kernel)  
 ("closed", closed) 

This is then converted to a binary map in order to obtain the contours of the image.

Finally, contour extraction is performed to capture the target

 # Find the outline
 _,contours, hierarchy = (binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)  
 #Drawing outlines
 (img,contours,-1,(0,0,255),3)  
 # Plotting results
 ("result", img)

All code:

#coding=utf-8
import cv2
import numpy as np
 
img = ("")                #Load image
h, w = [:2]                        # Get the height and width of the image
("Origin", img)                   # Show original image
 
blured = (img,(5,5))                # Filtering to remove noise
("Blur", blured)                  # Show low-pass filtered image
 
mask = ((h+2, w+2), np.uint8)       # The mask is two pixels longer and wider than the input image, and the full water fill does not extend beyond the non-zero edges of the mask
#Flood filling is performed
(blured, mask, (w-1,h-1), (255,255,255), (2,2,2),(3,3,3),8)
("floodfill", blured)
 
# Getting a grayscale map
gray = (blured,cv2.COLOR_BGR2GRAY)
("gray", gray)
 
 
# Define structure elements
kernel = (cv2.MORPH_RECT,(50, 50))
# Open and close operations, first open operation to remove background noise, then continue closed operation to fill the holes in the target
opened = (gray, cv2.MORPH_OPEN, kernel)
closed = (opened, cv2.MORPH_CLOSE, kernel)
("closed", closed)
 
#Find bipartite graphs
ret, binary = (closed,250,255,cv2.THRESH_BINARY)
("binary", binary)
 
# Find the outline
_,contours, hierarchy = (binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#Drawing outlines
 
(img,contours,-1,(0,0,255),3)
# Plotting results
("result", img)
 
(0)
()

summarize

To this article on how to use Python OpenCV to extract the contour of the object is introduced to this article, more related Python OpenCV to extract the contour of the object content, please search for my previous articles or continue to browse the following related articles I hope you will support me in the future more!