With input image as Contours_X.png
[Contours_X.png: PNG image data, 819 x 1154, 8-bit grayscale, non-interlaced] :
Stealing code from Python Find Contours white region only OpenCV code :
import cv2 as cv
import numpy as np
def generate_X_Y(image_path):
image = cv.imread(image_path)
# image = cv.imread(image_path, cv.IMREAD_UNCHANGED)
cv.imwrite("image_ori.png" , image)
print('image[0] : ', image[0])
gray = cv.cvtColor(image, cv.COLOR_RGBA2GRAY)
print('gray[0] : ', gray[0])
## CHANGED TO:
ret, thresh = cv.threshold(gray, 128, 255, cv.THRESH_BINARY_INV)
cv.imwrite("image2.png", thresh)
contours, hierarchies = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
blank = np.zeros(thresh.shape[:2], dtype='uint8')
cv.drawContours(blank, contours, -1, (255, 0, 0), 1)
cv.imwrite("Contours.png", blank)
print('len(contours) : ' , len(contours))
for i in contours:
cv.drawContours(image, [i], -1, (0, 255, 0), 2)
cv.imwrite("image.png", image)
if __name__ == '__main__':
image_path = 'Contours_X.png' # Provide the correct path in Colab
# image_path = 'input_alpha.png'
generate_X_Y(image_path)
I get output image.png
[image.png: PNG image data, 819 x 1154, 8-bit/color RGB, non-interlaced] :
While using input_alpha_2.png
[input_alpha_2.png: PNG image data, 1000 x 1200, 8-bit/color RGBA, non-interlaced] :
and code:
import cv2 as cv
import numpy as np
def generate_X_Y(image_path):
# image = cv.imread(image_path)
image = cv.imread(image_path, cv.IMREAD_UNCHANGED)
cv.imwrite("image_ori.png" , image)
print('image[0] : ', image[0])
gray = cv.cvtColor(image, cv.COLOR_RGBA2GRAY)
print('gray[0] : ', gray[0])
## CHANGED TO:
ret, thresh = cv.threshold(gray, 128, 255, cv.THRESH_BINARY_INV)
cv.imwrite("image2.png", thresh)
contours, hierarchies = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
blank = np.zeros(thresh.shape[:2], dtype='uint8')
cv.drawContours(blank, contours, -1, (255, 0, 0), 1)
cv.imwrite("Contours.png", blank)
print('len(contours) : ' , len(contours))
for i in contours:
cv.drawContours(image, [i], -1, (0, 255, 0), 20)
cv.imwrite("image.png", image)
if __name__ == '__main__':
# image_path = 'Contours_X.png' # Provide the correct path in Colab
image_path = 'input_alpha_2.png'
generate_X_Y(image_path)
I get image.png
[image.png: PNG image data, 1000 x 1200, 8-bit/color RGBA, non-interlaced] :
Why I don't get a nice green border around the subject like in first example?
As suggested in comments :
Your base BGR image (under the alpha channel) has your green lines. The alpha channel is covering it). Remove the alpha channel to see it.
and doing that with :
cv.imwrite("image.png", image[:,:,:3])
I get image.png: PNG image data, 1000 x 1200, 8-bit/color RGBA, non-interlaced :
but still I don't get how a transparent alpha channel could hide a contour and why do I get the gray background, that I believe could be the area of the biggest contour in my image the squared external black border?
cntsSorted = sorted(contours, key = lambda x: cv.contourArea(x) , reverse=True)
for index , i in enumerate(cntsSorted) :
print(cv.contourArea(i))
if index > 0 :
cv.drawContours(image, [i], -1, (0, 255, 0), 20)
cv.imwrite("image.png", image)
cv.imwrite("image_rem.png", image[:,:,:3])
The second image doesn't have the more external green border but still keeps the dark grey background.
Another way to also draw the contour on the image, since it has four channel, is to specify four channels in the contour drawing:
im = cv2.imread("disneyRGBA.png", cv2.IMREAD_UNCHANGED)
imContoured = im.copy()
imGray = cv2.cvtColor(im, cv2.COLOR_RGBA2GRAY)
ret, thresh = cv2.threshold(imGray, 128, 255, cv2.THRESH_BINARY_INV)
contours, hierarchies = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# I copied this from you, but you could have easily went with cv2.drawContours(imContoured, contours, -1, (0, 255, 0, 255), 20)
for i in contours:
imContoured = cv2.drawContours(imContoured, [i], -1, (0, 255, 0, 255), 20)
Here is the result after writing the image contoured with 255 on the alpha channel:
Here is the result after writing the image contoured with 0 on the alpha channel:
Same image from Adobephotoshop:
Using :
imContoured = cv2.drawContours(imContoured, [i], -1, (0, 255, 0, 0), 100)
0 on alpha channel and thicker contours (100) :
Here is the result after writing the image contoured with 127 on the alpha channel:
I somehow expected the other way around, that 255 is completely transparent and 0 is opaque. But seems to be the other way around.