Horacio Sanchez
Horacio Sanchez

Reputation: 39

Take photo when pattern is detected in image with Android OpenCV

Hello stackoverflow community I would like if someone can guide me a little regarding my next question, I want to make an application that takes a photo when it detects a sheet with 3 marks (black squares in the corners) similar to what a QR would have. I have read a little about opencv that I think could help me more however I am not very clear yet.

Here my example

Photo to capture with patterns

Upvotes: 2

Views: 217

Answers (1)

nathancy
nathancy

Reputation: 46680

Once you obtain your binary image, you can find contours and filter using contour approximation and contour area. If the approximated contour has a length of four then it must be a square and if it is within a lower and upper area range then we have detected a mark. We keep a counter of the mark and if there are three marks in the image, we can take the photo. Here's the visualization of the process.

We Otsu's threshold to obtain a binary image with the objects to detect in white.

enter image description here

From here we find contours using cv2.findContours and filter using contour approximation cv2.approxPolyDP in addition to contour area cv2.contourArea.

Detected marks highlighted in teal

enter image description here

I implemented it in Python but you can adapt the same approach

Code

import cv2

# Load image, grayscale, Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Find contours and filter using contour approximation and contour area
marks = 0
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    area = cv2.contourArea(c)
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.04 * peri, True)
    if len(approx) == 4 and area > 250 and area < 400:
        x,y,w,h = cv2.boundingRect(c)
        cv2.rectangle(image, (x, y), (x + w, y + h), (200,255,12), 2)
        marks += 1

# Sheet has 3 marks
if marks == 3:
    print('Take photo')

cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()

Upvotes: 2

Related Questions