Use OpenCV to identiy hollow and filled circles - python

I'm using OpenCV houghcircles to identify all the circles (both hollow and filled). Follow is my code:
import numpy as np
import cv2
img = cv2.imread('images/32x32.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
bilateral = cv2.bilateralFilter(gray,10,50,50)
minDist = 30
param1 = 30
param2 = 50
minRadius = 5
maxRadius = 100
circles = cv2.HoughCircles(bilateral, cv2.HOUGH_GRADIENT, 1, minDist, param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius)
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
cv2.circle(img, (i[0], i[1]), i[2], (0, 0, 255), 2)
# Show result for testing:
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Test input image 1:
Test output image1:
As you can see I'm able identity most of the circles except for few. What am I missing here? I've tried varying the parameters but this is the best i could get.
Also, if I use even more compact circles the script does not identify any circles whatsoever.

An alternative idea is to use find contour method and chek whether the contour is a circle using appox as below.
import cv2
img = cv2.imread('32x32.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
inputImageCopy = img.copy()
# Find the circle blobs on the binary mask:
contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Use a list to store the center and radius of the target circles:
detectedCircles = []
# Look for the outer contours:
for i, c in enumerate(contours):
# Approximate the contour to a circle:
(x, y), radius = cv2.minEnclosingCircle(c)
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
if len(approx)>5: # check if the contour is circle
# Compute the center and radius:
center = (int(x), int(y))
radius = int(radius)
# Draw the circles:
cv2.circle(inputImageCopy, center, radius, (0, 0, 255), 2)
# Store the center and radius:
detectedCircles.append([center, radius])
cv2.imshow("Circles", inputImageCopy)
cv2.waitKey(0)
cv2.destroyAllWindows()

I solved your problem. Using same code as your. No needed to modified. I changed value from 50 to 30. That all.
#!/usr/bin/python39
#OpenCV 4.5.5 Raspberry Pi 3/B/4B-w/4/8GB RAM, Bullseye,v11.
#Date: 19th April, 2022
import numpy as np
import cv2
img = cv2.imread('fill_circles.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
bilateral = cv2.bilateralFilter(gray,10,50,50)
minDist = 30
param1 = 30
param2 = 30
minRadius = 5
maxRadius = 100
circles = cv2.HoughCircles(bilateral, cv2.HOUGH_GRADIENT, 1, minDist, param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius)
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
cv2.circle(img, (i[0], i[1]), i[2], (0, 0, 255), 2)
cv2.imwrite('lego.png', img)
# Show result for testing:
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Output:

If you can always get(or create from real image) such "clean" image, the bounding-box of the grid(2-dimensional array of circles) region can be easily obtained.
Therefore, you can know the rectangular area of interest (and the angle of rotation of the grid, if rotation is possible).
If you examine the pixels along the axial direction of the rectangle, you can easily find out how many circles are lined up and the diameter of the circle.
Because lines that all pixel are black are gaps between adjacent row(or column).
(Sum up the pixel values along the direction of the axis. Whether it is 0 or not tells you whether the line passes over the grid-cell or not.)
If necessary, you may check that the shape of the contour in each gird-cell is really circular.

Related

how to remove background of everything outside circle in opencv python [duplicate]

This question already has an answer here:
How to blackout area outside circle with OpenCV Python?
(1 answer)
Closed 5 months ago.
I want the color code of circle (rgb) for that I have detected circle but doesn't know further process to dynamically mask/crop every background except inside circle
import numpy as np
import cv2
img = cv2.imread('4.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.medianBlur(gray, 25) #cv2.bilateralFilter(gray,10,50,50)
minDist = 100
param1 = 30 #500
param2 = 50 #200 #smaller value-> more false circles
minRadius = 5
maxRadius = 100 #10
# docstring of HoughCircles: HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]]) -> circles
circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, 1, minDist, param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius)
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
# Show result for testing:
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows() ````
The code in the question finds the circles using circles=cv2.HoughCircles() method of OpenCV which returns in case of the below shown image:
[[[226.5 211.5 111.6]
[597.5 364.5 108.2]
[498.5 145.5 95.9]]]
# ^ ^ ^
# x y r of found circles x,y == center and r == radius
Don't be fooled by the fact that there are float values returned for specifying integer pixel coordinates of the circle center in the image. They can be used as they are to preserve their precision or turned into integer values if necessary for indexing the corresponding pixel in the image to obtain its BGR color value (OpenCV uses by default BGR color format not RGB).
With the above results it's easy to create a mask by creating a new black image of same size as the original image mask = np.zeros_like(img) with white filled (specify thickness of the drawn circle line as -1 to get a filled circle) circles. With known coordinates of circle centers you can extract their BGR colors from the image array by indexing it with img[y,x]. If you want RGB just switch G and R in the color tuple.
import numpy as np
import cv2 as cv
img = cv.imread('circles.png')
cv.imshow('original image: circles.png', img)
cv.waitKey(0)
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
cv.imshow('gray image', img_gray)
cv.waitKey(0)
img_gray_blurred = cv.medianBlur(img_gray, 25) # cv.bilateralFilter(gray,10,50,50)
cv.imshow('gray/blurred image', img_gray_blurred)
cv.waitKey(0)
minDist = 10
param1 = 30 #500
param2 = 70 #200 # smaller value-> more false circles
minRadius = 5
maxRadius = 150 #10
# docstring of HoughCircles: HoughCircles(image, method, dp, minDist
# [, circles[, param1[, param2[, minRadius[, maxRadius]]]]]) -> circles
circles = cv.HoughCircles( img_gray_blurred,
cv.HOUGH_GRADIENT,
1,
minDist,
param1=param1, param2=param2,
minRadius=minRadius, maxRadius=maxRadius)
"""
print(circles) # gives float values for x, y, r of the cirles
[[[226.5 211.5 111.6]
[597.5 364.5 108.2]
[498.5 145.5 95.9]]]
"""
mask = np.zeros_like(img) # create empty black image with img size
white_color = (255, 255, 255)
line_color = (255, 0, 255)
filled_circle = -1
line_thickness = 3
if circles is not None: # found a circle or more than one circle
circles = np.uint16(np.around(circles)) # <-- turn float to integer
for i, (x, y, r) in enumerate(circles[0,:]):
cv.circle(img, (x, y), r, line_color, line_thickness)
print(f' Circle {i+1} center BGR is: {img[y,x]=}')
# draw filled circle in white on black background as mask:
mask = cv.circle(mask, (x, y), r, white_color, filled_circle)
# Apply mask to image
result = cv.bitwise_and(img, mask)
# Show result for testing:
cv.imshow('image with marked circles', img)
cv.waitKey(0)
cv.imshow('mask', mask)
cv.waitKey(0)
cv.imshow('masked image', result)
cv.waitKey(0)
cv.destroyAllWindows()
gives as output:
Circle 1 center BGR is: img[y,x]=array([ 18, 239, 57], dtype=uint8)
Circle 2 center BGR is: img[y,x]=array([ 64, 236, 13], dtype=uint8)
Circle 3 center BGR is: img[y,x]=array([ 6, 240, 105], dtype=uint8)

Detect circle in Opencv

When I try to detect circle from Coins Image:
In the first program, I use Matlab and everything works fine.
Now I try do detect The same circles from the coin's image but used OpenCV and I get a bad result.
I think that I do something wrong but I don't know what?
% This Example for Hough Transform Circles Matlab
% First step read image and make pre-processing
img = imread('coins2.png'); % Coins Image is Gray
figure, imshow(img), title('Orignal Coins Image');
edges = edge(img, 'Canny', [0.01, 0.5]);
figure, imshow(edges), title('Edge Image');
% Second Step Find all circles with radius [Rmin,Rmax]
Rmin = 10;
Rmax = 40;
[center, radii, metric] = imfindcircles(edges, [Rmin, Rmax]);
% Retain the N strongest circles according to the metric values
N = 24; % Hyperparam I can choose or I can display all circles that I get from the voting
centerStrong = center(1:N,:);
radiusStrong = radii(1:N);
metricStrong = metric(1:N);
% Draw the N strongest circle perimeters over the original image.
figure, imshow(img), hold on, viscircles(centerStrong, radiusStrong,'EdgeColor','b'),
title('Circle Segment'), hold off;
# Python exam:
import cv2
img = cv2.imread('coins2.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Convert the image to gray scale
edges = cv2.Canny(image=gray, threshold1=200, threshold2=100, apertureSize=3)
cv2.imshow('Orignal Image', img), cv2.imshow('Edge Image', edges)
circles = cv2.HoughCircles(image=edges, method=cv2.HOUGH_GRADIENT, dp=20, minDist=1,
param1=30, param2=50, minRadius=10, maxRadius=50)
for circle in circles[0, :]:
a, b = int(circle[0]), int(circle[1])
radius = int(circle[2])
cv2.circle(img=img, center=(a, b), radius=radius, color=(255, 0, 0), thickness=2)
cv2.imshow('Circle Segment', img), cv2.waitKey(0), cv2.destroyAllWindows()
Thanks to everyone for the answers it was very helpful.
Attached the code that brought me almost the same MATLAB performance.
import cv2
img = cv2.imread('coins2.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Convert the image to gray scale
thres=230
edges = cv2.Canny(image=gray, threshold1=thres, threshold2=thres/2,
apertureSize=3, L2gradient=True)
cv2.imshow('Orignal Image', img), cv2.imshow('Edge Image', edges)
circles = cv2.HoughCircles(image=gray, method=cv2.HOUGH_GRADIENT, dp=0.06,
minDist=14, param1=thres, param2=30, minRadius=10,
maxRadius=40)
for circle in circles[0, :]:
a, b = int(circle[0]), int(circle[1])
radius = int(circle[2])
cv2.circle(img=img, center=(a, b), radius=radius, color=(255, 0, 0),
thickness=2)
cv2.imshow('Circle Segment', img), cv2.waitKey(0), cv2.destroyAllWindows()

Detect circles in openCV

I have a problem with choosing right parameters for HoughCircles function. I try to detect circles from video. This circles are made by me, and has almost the same dimension. Problem is that camera is in move.
When I change maxRadius it still detect bigger circles somehow (see the right picture). I also tried to change param1, param2 but still no success.
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.medianBlur(gray, 25)#cv2.bilateralFilter(gray,10,50,50)
minDist = 100
param1 = 500
param2 = 200#smaller value-> more false circles
minRadius = 5
maxRadius = 10
circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, 1, minDist, param1, param2, minRadius, maxRadius)
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
cv2.circle(blurred,(i[0], i[1]), i[2], (0, 255, 0), 2)
Maybe Im using wrong function?
The main problem in your code is 5th argument to HoughCircles function.
According to documentation the argument list is:
cv2.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]]) → circles
That means the 5th argument applies circles (it gives an option getting the output by reference, instead of using the returned value).
Because you are not passing circles argument, you must pass named arguments for all arguments after the 4th argument (like param1=param1, param2=param2....).
Parameter tuning issues:
Reduce the value of param1.
param1 is the higher threshold passed to the Canny.
In your case value should be about 30.
Reduce the value of param2
The documentation not so clear, but setting the value around 50 works.
Increase maxRadius value - radius 10 is much smaller than the radius of your circles.
Here is the code:
import numpy as np
import cv2
img = cv2.imread('circles.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.medianBlur(gray, 25) #cv2.bilateralFilter(gray,10,50,50)
minDist = 100
param1 = 30 #500
param2 = 50 #200 #smaller value-> more false circles
minRadius = 5
maxRadius = 100 #10
# docstring of HoughCircles: HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]]) -> circles
circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, 1, minDist, param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius)
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
# Show result for testing:
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Result:
Instead of having to fiddle with choosing the right parameters with cv2.HoughCircles, here's an alternative approach using contour filtering. The idea is to obtain a binary image with Otsu's threshold then perform morphological operations to isolate elliptical shaped contours. Finally we find contours and filter using aspect ratio and contour area. Here's the results:
import cv2
import numpy as np
# Load image, grayscale, median blur, Otsus threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.medianBlur(gray, 11)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# Morph open
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=3)
# Find contours and filter using contour area and aspect ratio
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.04 * peri, True)
area = cv2.contourArea(c)
if len(approx) > 5 and area > 1000 and area < 500000:
((x, y), r) = cv2.minEnclosingCircle(c)
cv2.circle(image, (int(x), int(y)), int(r), (36, 255, 12), 2)
cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.imshow('image', image)
cv2.waitKey()

Detect multiple circles in an image

I am trying to detect the count of water pipes in this picture. For this, I am trying to use OpenCV and Python-based detection. The results, I am getting is a little confusing to me because the spread of circles is way too large and inaccurate.
The code
import numpy as np
import argparse
import cv2
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required = True, help = "Path to the image")
args = vars(ap.parse_args())
# load the image, clone it for output, and then convert it to grayscale
image = cv2.imread(args["image"])
output = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#detect circles in the image
#circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1.2, param1=40,minRadius=10,maxRadius=35)
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 8.5,70,minRadius=0,maxRadius=70)
#print(len(circles[0][0]))
# ensure at least some circles were found
if circles is not None:
# convert the (x, y) coordinates and radius of the circles to integers
circles = np.round(circles[0, :]).astype("int")
# count = count+1
# print(count)
# loop over the (x, y) coordinates and radius of the circles
for (x, y, r) in circles:
# draw the circle in the output image, then draw a rectangle
# corresponding to the center of the circle
cv2.circle(output, (x, y), r, (0, 255, 0), 4)
cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)
# show the output image
# cv2.imshow("output", np.hstack([output]))
cv2.imwrite('output.jpg',np.hstack([output]),[cv2.IMWRITE_JPEG_QUALITY, 70])
cv2.waitKey(0)
After I run this, I do see a lot of circles detected, however, the results are complete haywire.
My question is, how do I improve this detection. Which parameters are specifically needed to optimize in the HoughCircles method to achieve greater accuracy? Or, should I take the approach of annotating hundreds of similar images via bounding boxes and then train them over a full-blown CNN like Yolo to perform detection?
Taking the approach mentioned in answer number 2 from here Measuring the diameter pictures of holes in metal parts, photographed with telecentric, monochrome camera with opencv . I got this output. This looks close to performing a count but misses on lot of actual pipes during the brightness transformation of the image.
The most important parameters for your HoughCircles call are:
param1: because you are using cv2.HOUGH_GRADIENT, param1 is the higher threshold for the edge detection algorithm and param1 / 2 is the lower threshold.
param2: it represents the accumulator threshold, so the lower the value, the more circles will be returned.
minRadius and maxRadius: the blue circles in the example have a diameter of roughly 20 pixels, so using 70 pixels for maxRadius is the reason why so many circles are being returned by the algorithm.
minDist: the minimum distance between the centers of two circles.
The parameterization defined below:
circles = cv2.HoughCircles(gray,
cv2.HOUGH_GRADIENT,
minDist=6,
dp=1.1,
param1=150,
param2=15,
minRadius=6,
maxRadius=10)
returns:
You could do an adaptive threshold as preprocessing. This basically looks for areas that are relatively brighter than the neighboring pixels, your global threshold loses some of the pipes, this keeps them a little better.
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('a2MTm.jpg')
blur_hor = cv2.filter2D(img[:, :, 0], cv2.CV_32F, kernel=np.ones((11,1,1), np.float32)/11.0, borderType=cv2.BORDER_CONSTANT)
blur_vert = cv2.filter2D(img[:, :, 0], cv2.CV_32F, kernel=np.ones((1,11,1), np.float32)/11.0, borderType=cv2.BORDER_CONSTANT)
mask = ((img[:,:,0]>blur_hor*1.2) | (img[:,:,0]>blur_vert*1.2)).astype(np.uint8)*255
plt.imshow(mask)
You can then carry on with the same post processing steps.
Here are some example processing steps:
circles = cv2.HoughCircles(mask,
cv2.HOUGH_GRADIENT,
minDist=8,
dp=1,
param1=150,
param2=12,
minRadius=4,
maxRadius=10)
output = img.copy()
for (x, y, r) in circles[0, :, :]:
cv2.circle(output, (x, y), r, (0, 255, 0), 4)
You can adjust the parameters to get what you would like, read about the parameters here.
Instead of using cv2.HoughCircles another approach would be to use contour filtering. We can threshold the image then filter using aspect ratio, contour area, and radius of the blob. Here's the result:
Count: 344
Code
import cv2
image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,27,3)
cnts = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
count = 0
for c in cnts:
area = cv2.contourArea(c)
x,y,w,h = cv2.boundingRect(c)
ratio = w/h
((x, y), r) = cv2.minEnclosingCircle(c)
if ratio > .85 and ratio < 1.20 and area > 50 and area < 120 and r < 7:
cv2.circle(image, (int(x), int(y)), int(r), (36, 255, 12), -1)
count += 1
print('Count: {}'.format(count))
cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()

Detecting Overlapping Circles in OpenCV

I'm using the OpenCV library for Python to detect the circles in an image. As a test case, I'm using the following image:
bottom of can:
I've written the following code, which should display the image before detection, then display the image with the detected circles added:
import cv2
import numpy as np
image = cv2.imread('can.png')
image_rgb = image.copy()
image_copy = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
grayscaled_image = cv2.cvtColor(image_copy, cv2.COLOR_GRAY2BGR)
cv2.imshow("confirm", grayscaled_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
circles = cv2.HoughCircles(image_copy, cv2.HOUGH_GRADIENT, 1.3, 20, param1=60, param2=33, minRadius=10,maxRadius=28)
if circles is not None:
print("FOUND CIRCLES")
circles = np.round(circles[0, :]).astype("int")
print(circles)
for (x, y, r) in circles:
cv2.circle(image, (x, y), r, (255, 0, 0), 4)
cv2.rectangle(image, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)
cv2.imshow("Test", image + image_rgb)
cv2.waitKey(0)
cv2.destroyAllWindows()
I get this:resultant image
I feel that my problem lies in the usage of the HoughCircles() function. It's usage is:
cv2.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]])
where minDist is a value greater than 0 that requires detected circles to be a certain distance from one another. With this requirement, it would be impossible for me to properly detect all of the circles on the bottom of the can, as the center of each circle is in the same place. Would contours be a solution? How can I convert contours to circles so that I may use the coordinates of their center points? What should I do to best detect the circle objects for each ring in the bottom of the can?
Not all but a majority of the circles can be detected by adaptive thresholding the image, finding the contours and then fitting a minimum enclosing circle for contours having area greater than a threshold
import cv2
import numpy as np
block_size,constant_c ,min_cnt_area = 9,1,400
img = cv2.imread('viMmP.png')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(img_gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,block_size,constant_c)
thresh_copy = thresh.copy()
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
if cv2.contourArea(cnt)>min_cnt_area:
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
cv2.circle(img,center,radius,(255,0,0),1)
cv2.imshow("Thresholded Image",thresh_copy)
cv2.imshow("Image with circles",img)
cv2.waitKey(0)
Now this script yields the result:
But there are certain trade-offs like, if the block_size and constant_c are changed to 11 and 2 respectively then the script yields:
You should try applying erosion with a kernel of proper shape to separate the overlapping circles in the thresholded image
You may look at the following links to understand more about adaptive thresholding and contours:
Threshlding examples: http://docs.opencv.org/3.1.0/d7/d4d/tutorial_py_thresholding.html
Thresholding reference: http://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html
Contour Examples:
http://docs.opencv.org/3.1.0/dd/d49/tutorial_py_contour_features.html

Categories

Resources