detect and count the number of star symbol in opencv-python

Question:

I need to count the occurrence of the stars at the right bottom corner in the image, I read this article
Template Matching
and used the following code to find the stars but My code doesn’t work for detecting the stars in the image.

What changes should I make in the code?

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img_rgb = cv.imread('page.png')
img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)
template = cv.imread('star_temp.png', 0)
w, h = template.shape[::-1]
res = cv.matchTemplate(img_gray, template, cv.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where(res >= threshold)
print(res)
for pt in zip(*loc[::-1]):
    cv.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2)
cv.imwrite('res.png', img_rgb)

star_temp.png

enter image description here

page.png

enter image description here

Asked By: Ekoar

||

Answers:

It’s because your template is bigger than the actual star on the image. Template matching is not scale invariant, so you need to be careful and match an almost same-size image. I cropped this from your target image:

1

This is the full working snippet:

import cv2

# image path
path = "D://opencvImages//"

# Reading images in default mode:
targetImage = cv2.imread(path + "d6tu1.png")
templateImage = cv2.imread(path + "starTemplate.png")

# Deep copy for results:
targetImageCopy = targetImage.copy()

# Convert RGB to grayscale:
grayscaleImage = cv2.cvtColor(targetImage, cv2.COLOR_BGR2GRAY)
grayscaleTemplate = cv2.cvtColor(templateImage, cv2.COLOR_BGR2GRAY)

# Perform template match:
matchResult = cv2.matchTemplate(grayscaleImage, grayscaleTemplate, cv2.TM_CCOEFF_NORMED)
# Set matching minimum score:
threshold = 0.9
loc = np.where( matchResult >= threshold)

# Look for possible matches:
matchesCounter = 0
w, h = grayscaleTemplate.shape[::-1]

for pt in zip(*loc[::-1]):
    cv2.rectangle(targetImageCopy, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)

    # increase number of matches:
    matchesCounter +=1

    cv2.imshow("Matches", targetImageCopy)
    cv2.waitKey(0)

print("Number of matches: "+str(matchesCounter))

You end up with this result:

enter image description here

Number of matches: 3
Answered By: stateMachine