Reputation: 3061
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.
Upvotes: 0
Views: 170
Reputation: 2648
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.
Upvotes: 1
Reputation: 53071
My python/opencv is broke at the moment. So if I take your transparent image
and remove the alpha channel in Imagemagick, I get
convert image.png -alpha off x.png
Perhaps you are using the wrong input image?
Upvotes: 1