Reputation: 387
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.
Upvotes: 1
Views: 817
Reputation: 4561
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.
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()
Upvotes: 4
Reputation: 207670
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.
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.
Upvotes: 2