简体   繁体   中英

Python -Rectangular Contour on a single color on image

I am trying to draw a rectangular contour around a green image

I am able to draw the biggest rectangle but unable to draw specifically on a single colour.

Any help would be great.

需要轮廓的图像

The expected result is cropped image of the bright green part in rectangular shape.

My code is - :

import cv2
import numpy as np

median = cv2.imread("try.png", 0)
image_gray = median 
image_gray = np.where(image_gray > 30, 255, image_gray)
image_gray = np.where(image_gray <= 30, 0, image_gray)
image_gray = cv2.adaptiveThreshold(image_gray, 255,
                           cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                           cv2.THRESH_BINARY_INV, 115, 1)
_, contours, _ = cv2.findContours(image_gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
rect_cnts = []
for cnt in contours:
    peri = cv2.arcLength(cnt, True)
    approx = cv2.approxPolyDP(cnt, 0.04 * peri, True)
    (x, y, w, h) = cv2.boundingRect(cnt)
    ar = w / float(h)
    if len(approx) == 4: # shape filtering condition
        rect_cnts.append(cnt)
max_area = 0
football_square = None
for cnt in rect_cnts:
    (x, y, w, h) = cv2.boundingRect(cnt)
    if max_area < w*h:
        max_area = w*h
        football_square = cnt

# Draw the result
image = cv2.cvtColor(image_gray, cv2.COLOR_GRAY2RGB)
cv2.drawContours(image, [football_square], -1, (0, 0,255), 5)
cv2.imshow("Result Preview", image)
cv2.waitKey()

Any suggestions and help would be great to help me draw contour over a single color only in rectangular shape which is screen.

As @MarkSetchell says, other colorspaces can make this easier. For instance, below I converted your image to HSV. Then I used inRange to create a mask that holds the bright green area's. Next the largest contour is selected, which is the screen. Then the boundingRect of the contour is used to create a new image.

Result:
在此处输入图片说明

Code:

import numpy as np 
import cv2
# load image
image = cv2.imread('d3.jpg')
# create hsv
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

 # set lower and upper color limits
low_val = (60,180,160)
high_val = (179,255,255)
# Threshold the HSV image 
mask = cv2.inRange(hsv, low_val,high_val)
# find contours in mask
ret, contours, hierarchy = cv2.findContours(mask,cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# select the largest contour
largest_area = 0
for cnt in contours:
    if cv2.contourArea(cnt) > largest_area:
        cont = cnt
        largest_area = cv2.contourArea(cnt)

# get the parameters of the boundingbox
x,y,w,h = cv2.boundingRect(cont)

# create and show subimage
roi = image[y:y+h, x:x+w]
cv2.imshow("Result", roi)

#  draw box on original image and show image
cv2.rectangle(image, (x,y),(x+w,y+h), (0,0,255),2)
cv2.imshow("Image", image)

cv2.waitKey(0)
cv2.destroyAllWindows()

Often you can get a good idea of how to separate objects in an image by converting it to different colorspaces and splitting out the individual channels to see which are best at differentiating colours. So, if you do that to your image, you get this:

在此处输入图片说明

  • The top row is the image in Lab colourspace, with Lightness on the left, then a then b ,

  • The second row is in HSL colourspace, with Hue on the left, then Saturation , then Lightness .

The subsequent rows are YIQ , XYZ , RGB .

You can get each of these in OpenCV using cvtColor() .

Now you look at the images and see what will differentiate your LCD display.

  • Green looks good but includes the yellow above the left side of the LCD
  • Likewise Lightness
  • Saturation looks good, but also includes the bottom-right corner of the image

It looks like a in the top row and Q in the third row might be good and you would threshold in both cases to get dark tones.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM