Python opencv drawContours does not show anything - python

I followed the tutorial at this page but nothing seems to happen when the line cv2.drawContours(im,contours,-1,(0,255,0),3) is executed. I was expecting to see star.jpg with a green outline, as shown in the tutorial. Here is my code:
import numpy as np
import cv2
im = cv2.imread('C:\Temp\ip\star.jpg')
print im.shape #check if the image is loaded correctly
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(im,contours,-1,(0,255,0),3)
pass
There are no error messages. star.jpg is the star from the above mentioned webpage.
I am using opencv version 2.4.8 and Python 2.7.
Is drawContours supposed to show an image on my screen? If so, what did I do wrong? If not, how do I show the image?
Thanks
Edit:
Adding the following lines will show the image:
cv2.imshow("window title", im)
cv2.waitKey()
waitKey() is needed otherwise the window will just show a gray background. According to this post, that's because waitKey() tells it to start handling the WM_PAINT event.

I had the same issue. I believe the issue is that the underlying image is 1-channel rather than 3-channel. Therefore, you need to set the color so it's nonzero in the first element (e.g. (255,0,0)).

i too had the same problem. The thing is it shows, but too dark for our eyes to see.
Solution:
change the colour from (0,255,0) (for some weird reason, i too had give exactly the same color!) to (128,255,0) (or some better brighter colour)

You have to do something to the effect of:
cv2.drawContours(im,contours,-1,(255,255,0),3)
cv2.imshow("Keypoints", im)
cv2.waitKey(0)

I guess your original image is in gray bit plane. Since your bit plane is Gray instead of BGR and so the contour is not showing up. Because it's slightly black and grey which you cannot distinguish. Here's the simple solution [By converting the bit plane]:
im=cv2.cvtColor(im,cv2.COLOR_GRAY2BGR)
cv2.drawContours(im,contours,-1,(0,255,0),3)

Related

Error when trying to change the default colour of rectangle in OpenCV

I'm working to create bounding boxes around the data I need to extract from an image. (I am using Jupyter notebook for python and OpenCV).
For this, I am drawing rectangles of desired coordinates and am using the following line of code:
cv2.rectangle(img,(50,82),(440,121), (0, 255, 0), 1)
This is for some reason giving only a black rectangle even though (0,255,0) is supposed to give green. What's more, if I use any other colour, for example (255,255,0), the box doesn't appear at all.
Thanks in advance for your help!
Is the image img that you are drawing on binary or grayscale? If so, make it color by merging the same image 3 times so that you have an RGB image with R=G=B. Or convert it Gray2BGR using cvtColor(). That is in Python/OpenCV do either
img = cv2.merge([img,img,img])
or
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGB)

How does cv2.findContours() edit the image?

I have two questions.
I am working with openCv and python and I am trying to have an image's contours. I am succesfull at that but when I try to se what is the difference between when I use cv2.drawContorus() functions and directly edit image with cv2.findContours() without sending a copy of original image as the source parameter. I have tried on some images but I couldnt see anything even happenning.
I am trying to get the contours of a square I created with paint square tool. But when I try with cv2.CHAIN_APPROX_SIMPLE method, it gives me coordinates of 6 points which none of the combinations from them is suitable for my square. Why does it do like that?
Can someone explain?
Here is my code for both problems:
import cv2
import numpy as np
image = cv2.imread(r"C:\Users\fazil\Desktop\12.png")
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
gray = cv2.Canny(gray,75,200)
gray = cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV)[1]
cv2.imshow("s",gray)
contours, hiearchy = cv2.findContours(gray,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
print(contours[1])
cv2.drawContours(image,contours,1,(45,67,89),5)
cv2.imshow("k",gray)
cv2.imshow("j",image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Strange image display artifacts using ArUco Markers with OpenCV and Python

I'm using OpenCV 3.4 and Python 3.6 and attempting to read ArUco marker. I'm having success but I'm seeing an unexpected issue and am hoping that someone can steer me in the right direction.
import numpy as np
import cv2
import cv2.aruco as aruco
test_dict = aruco.getPredefinedDictionary(aruco.DICT_6X6_50)
img = cv2.imread(test.jpg)
corners, ids, rejects = aruco.detectMarkers(img, test_dict)
markerImg = aruco.drawDetectedMarkers(img, corners)
rejectImg = aruco.drawDetectedMarkers(img, rejects)
stackedImage = np.hstack((markerImage, rejectImage))
cv2.imshow("Accepts and Rejects", stackedImage)
cv2.waitKey(0)
cv2.destroyAllWindows()
The strangeness is that the stacked images are identical. Both rejects and detects are the same. If I comment out the line performing the draw of the rejects I see only the detected markers, and vice versa.
Anyone have any ideas as to what is causing this?
I was able to determine the cause of the issue I was encountering. The function:
markerImage = aruco.drawDetectedMarkers(img, corners)
was setting markerImage and img to be the exact same object such that
markerImage is img
returned as True.
To avoid this problem I coped img using:
markerImage = img.copy()
aruco.drawDetectedMarkers(markerImage, corners)
This functionality is significantly different from most of my experience so hopefully it will help someone in the future.

OpenCV cv2.rectangle output binary image

I have been trying to draw rectangle on a black image, uscv2.rectangle.Here is my code : (It is just a sample, in actual code there is a loop i.e values x2,y2,w2,h2 changes in a loop)
heir = np.zeros((np.shape(image1)[0],np.shape(image1)[1]),np.uint8);
cv2.rectangle(heir,(x2,y2),(x2+w2,y2+h2),(255,255,0),5)
cv2.imshow("img",heir);
cv2.waitKey()
It is giving the following output:
Why the image is like that? Why the boundaries are not just a line a width 5.
I have tried, but I am not able to figure it out.
Can't post this in a comment, but it's a negative answer: the same operations work for me on Windows/python 2.7.8/opencv3.1
import numpy as np
import cv2
heir = np.zeros((100,200),np.uint8);
x2=10
y2=20
w2=30
h2=40
cv2.rectangle(heir,(x2,y2),(x2+w2,y2+h2),(255,255,0),5)
cv2.imshow("img",heir);
cv2.waitKey()
Because you are loading the image to be tagged (draw rectangles) in grayscale, thats why when you are adding rectangles/bounding boxes the colors are being converted to grayscale.
To fix the issue, open image in "color" format. Since, you didn't included that part of code, here is the proposed solution:
tag_img = cv2.imread(MYIMAGE,1)
Pay attention to the second parameter here, which is "1" and means load image as color. Read more about reading images here: https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_image_display/py_image_display.html

Python PIL: Convert RGBA->P - ValueError: image has wrong mode [duplicate]

I would like to convert a PNG32 image (with transparency) to PNG8 with Python Image Library.
So far I have succeeded converting to PNG8 with a solid background.
Below is what I am doing:
from PIL import Image
im = Image.open("logo_256.png")
im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)
im.save("logo_py.png", colors=255)
After much searching on the net, here is the code to accomplish what I asked for:
from PIL import Image
im = Image.open("logo_256.png")
# PIL complains if you don't load explicitly
im.load()
# Get the alpha band
alpha = im.split()[-1]
im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)
# Set all pixel values below 128 to 255,
# and the rest to 0
mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0)
# Paste the color of index 255 and use alpha as a mask
im.paste(255, mask)
# The transparency index is 255
im.save("logo_py.png", transparency=255)
Source: http://nadiana.com/pil-tips-converting-png-gif
Although the code there does not call im.load(), and thus crashes on my version of os/python/pil. (It looks like that is the bug in PIL).
As mentioned by Mark Ransom, your paletized image will only have one transparency level.
When saving your paletized image, you'll have to specify which color index you want to be the transparent color like this :
im.save("logo_py.png", transparency=0)
to save the image as a paletized colors and using the first color as a transparent color.
This is an old question so perhaps older answers are tuned to older version of PIL?
But for anyone coming to this with Pillow>=6.0.0 then the following answer is many magnitudes faster and simpler.
im = Image.open('png32_or_png64_with_alpha.png')
im = im.quantize()
im.save('png8_with_alpha_channel_preserved.png')
Don't use PIL to generate the palette, as it can't handle RGBA properly and has quite limited quantization algorithm.
Use pngquant instead.

Categories

Resources