Today I learned one simple shape detection algorithm. In contrast image, it tries to find how many corners on some shapes are. When there is three, then it is a triangle and so on. And draws coloured contour around it. In a controlled environment, it works mostly as supposed. When you released it to the real wild world it gives quite artistic results.
#!/usr/bin/env python3
'''
Shape detection from images.
Tauno Erik
13.05.2021
'''
import cv2 as cv
import os
# Colors (BGR)
RED = (0,0,255)
GREEN = (0,255,0)
BLUE = (255,0,0)
YELLOW = (0,255,255)
CYAN = (255,255,0)
MAGENTA = (255,0,255)
ORANGE = (0,140,255)
PINK = (147,20,255)
PURPLE = (128,0,128)
GOLDEN = (32,165,218)
BROWN = (42,42,165)
def full_path(filename):
''' Returns full path to file. '''
folder = os.path.dirname(__file__) # File location
full_path = os.path.join(folder, filename)
return full_path
def shape_detection(file):
img = cv.imread(file)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(gray, 50, 255, 1)
contours, h = cv.findContours(thresh, 1, 2)
img_hall = cv.cvtColor(gray, cv.COLOR_GRAY2BGR)
for cnt in contours:
approx = cv.approxPolyDP(cnt, 0.01*cv.arcLength(cnt, True), True) # Returns array
print("Shape with {} pints".format(len(approx)))
n = len(approx)
if n is 15 or n is 16:
cv.drawContours(img_hall, [cnt], 0, YELLOW, 5)
elif n is 12:
cv.drawContours(img_hall, [cnt], 0, BROWN, 5)
elif n is 11:
cv.drawContours(img_hall, [cnt], 0, GOLDEN, 5)
elif n is 10:
cv.drawContours(img_hall, [cnt], 0, PURPLE, 5)
elif n is 9:
cv.drawContours(img_hall, [cnt], 0, PINK, 5)
elif n is 8:
cv.drawContours(img_hall, [cnt], 0, CYAN, 5)
elif n is 7:
cv.drawContours(img_hall, [cnt], 0, ORANGE, 5)
elif n is 6:
cv.drawContours(img_hall, [cnt], 0, CYAN, 5)
elif n is 5:
cv.drawContours(img_hall, [cnt], 0, RED, 5)
elif n is 4:
cv.drawContours(img_hall, [cnt], 0, GREEN, 5)
elif n is 3:
cv.drawContours(img_hall, [cnt], 0, BLUE, 5)
cv.imshow('Shaps', img_hall)
cv.waitKey(0)
if __name__ == "__main__":
print('Shape detection!')
print('To close window press: q')
file = full_path('images/kujundid.jpg')
shape_detection(file)
That’d probably be quite helpful to new artists trying to spot the big shapes (and negative space) in a subject they’re trying to paint.
Cool effect in the video too. 🙂
That’s an interesting idea. Maybe also to analyse the composition of paintings. I have to try it.
Another good idea!