Reputation: 5355
I am having the following image and would like to detect the red rectangle to cut it away:
On the right side is the wanted result
.
I tried the following:
!curl -o messi_card_hor.jpg https://d1w8cc2yygc27j.cloudfront.net/-2675427100542262593/7010047673982964277.jpg
!curl -o ronaldo_card.jpg https://d1w8cc2yygc27j.cloudfront.net/-6081046349913684185/-7772716368837553466.jpg
!curl -o ronaldo_sticker.jpg https://d1w8cc2yygc27j.cloudfront.net/6559100964212657924/2938835010875297356.jpg
!curl -o mini.jpg https://d1w8cc2yygc27j.cloudfront.net/-2342182173466831883/-5809028710077412417.jpg
!curl -o maradonna.jpg https://d1w8cc2yygc27j.cloudfront.net/-7109542822702569515/-8340360203776679658.jpg
!curl -o mess.jpg https://d1w8cc2yygc27j.cloudfront.net/-8505602657852037324/-5181528839070911125.jpg
!curl -o thierry.jpg https://d1w8cc2yygc27j.cloudfront.net/-5353994491295474458/6765375063661749632.jpg
# import cv
import cv2
import numpy as np
import sys
from google.colab.patches import cv2_imshow
import ipdb
%pdb on
def get_new(old):
new = np.ones(old.shape, np.uint8)
cv2.bitwise_not(new,new)
return new
#START
def detectRedBorder(img):
orig = cv2.imread(img)
baseImg = orig
result = orig.copy()
orig = cv2.cvtColor(orig, cv2.COLOR_BGR2HSV)
lower = np.array([155,25,0])
upper = np.array([179,255,255])
mask = cv2.inRange(orig, lower, upper)
result = cv2.bitwise_and(result, result, mask=mask)
print("baseImg:")
# cv2.imshow('mask', mask)
cv2_imshow(baseImg)
print("mask:")
# cv2.imshow('mask', mask)
cv2_imshow(mask)
print("result:")
# cv2.imshow('result', result)
cv2_imshow(result)
# cv2.waitKey()
cv2.destroyAllWindows()
# run script
detectRedBorder("./messi_card_hor.jpg")
detectRedBorder("./ronaldo_card.jpg")
detectRedBorder("./ronaldo_sticker.jpg")
detectRedBorder("./mini.jpg")
detectRedBorder("./maradonna.jpg")
detectRedBorder("./mess.jpg")
detectRedBorder("./thierry.jpg")
Find here the google colab with the executable code.
I am successfully creating the mask, BUT still I am struggeling how to identify the rectangle and crop it away.
I really appeciate your replies!
Upvotes: 0
Views: 537
Reputation: 4561
A bunch of those images are very consistent. For those you could detect the orientation and simply cut off the top x pixels.
Otherwise you can sum the rows of the mask you created with inrange.
sumOfRows = numpy.sum(img, axis=1)
With proper masking the expected values will start at or near zero at the top of the card, become significantly higher at the red border and below that become (near) zero again.
A third approach is to use findcontours on the mask, select the largest contour (presumably the red border) and find the highest y coordinate of the contour (= the lowest point on the red border).
Upvotes: 1