0

My python code takes a screenshot of by desktop and looks for a red rectangle on a black background, when I use the cv2.findcountours it doesn't return an exact sized rectangle, it seems to be distorted. I would like to obtain the exact area of the shape. Also, the image on my screenshot has no pixelation and borders are sharp. Thanks for your help!

frame_TS_new_raw = np.array(sct.grab(monitor_TS_new))
frame_TS_new = cv2.cvtColor(frame_TS_new_raw, cv2.COLOR_RGBA2RGB)

green_mask_TS_new = cv2.inRange(frame_TS_new,green_lower_range, green_upper_range)

# find contours for New TS
cnts_green_new = cv2.findContours(green_mask_TS_new.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts_green_new = cnts_green_new[0] if imutils.is_cv2() else cnts_green_new[1]
if len(cnts_green_new) > 0:
    for c in cnts_green_new:
        # if the contour is not sufficiently large, ignore it
        if cv2.contourArea(c) > 100:
            area = cv2.contourArea(c)

screenshot of the masked and unmasked

enter image description here

The image on the left is raw screenshot and the image on the right is the masked.

2
  • What do you mean "image on the left" and "image on the right" -- there's just one giant white image with two tiny blobs in the top left corner... Commented Apr 24, 2018 at 18:04
  • Yes thank you I edited the image to make it larger. Thanks Commented Apr 24, 2018 at 18:44

1 Answer 1

1

To find area of red rectangle in the image you can do as:

  • extract red channel of the image
  • threshold red channel
  • count number of nonzero pixels

Example code:

import cv2
import numpy as np

img = cv2.imread('vju0v.png')
img = np.array(img) # convert to numpy array
red = img[:,:,2]    # extract red channel
rect = np.float32(red > 200)   # find red pixels
area = np.sum(rect)    # count nonzero pixels

print('Area = ' + str(area))

cv2.imshow('Red Channel',rect)
cv2.waitKey(0)
Sign up to request clarification or add additional context in comments.

5 Comments

Is there any way that I can use this method of counting the pixels but use a range because I need to detect three different colors of red but I dont want to overlap other colors (dark red and gray for example)?
you can define your range as rect = np.float32(red > 200 and red < 225)
What about a range for the other colors like if I want red to be from 30 to 255, green 0 to 100, blue 0 to 85?
you can get three channels as red = img[:,:,2] and green = img[:,:,1] and blue = img[:,:,0] and use your range to get colors
I get this error: rect = np.float32(red > 30 and red < 255) # find red pixels ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.