Access Image via OpenCV in python (ROS Kinetic) - python-2.7

I want to access my camera using OpenCV in ros kinetic,
this is my code
#!/usr/bin/env python2.7
import rospy
from sensor_msgs.msg import Image
import cv2
from cv_bridge import CvBridge, CvBridgeError
rospy.init_node('opencv_example', anonymous=True)
bridge = CvBridge()
def show_image(img):
cv2.imshow("Image Window", img)
cv2.waitKey(3)
def image_callback(img_msg):
try:
cv_image = bridge.imgmsg_to_cv2(img_msg, "passthrough")
except CvBridgeError, e:
rospy.logerr("CvBridge Error: {0}".format(e))
show_image(cv_image)
sub_image = rospy.Subscriber("/raspicam_node/image/compressed", Image, image_callback)
cv2.namedWindow("Image Window", 1)
while not rospy.is_shutdown():
rospy.spin()
all I get after this code is a blank image window
before you ask the topic address, I can access the camera with this command rostrum image_view image_view image:=/raspicam_node/image/ _image_transport:=compressed
currently, I am working with
Ubuntu 16.04
Ros Kinetic
Open CV 3.3.1

You've answered your own question, the image is coming in compressed. Because of this your subscriber is also wrong there is a specific sensor_msgs type for Compressed Images.
Using numpy you can decode the image directly in your subscriber like so:
def image_callback(img_msg):
np_arr = np.fromstring(img_msg.data, np.uint8)
image_np = cv2.imdecode(np_arr, cv2.CV_LOAD_IMAGE_COLOR)
show_image(cv_image)
As stated earlier, your subscriber also needs to look like
sub_image = rospy.Subscriber("/raspicam_node/image/compressed", CompressedImage, image_callback)
And you need to include from sensor_msgs.msg import CompressedImage
Edit:
Based on your comment you can also republish the compressed image as an uncompressed image to use with your original code using image_transport.
If you want to use rosrun in the terminal: rosrun image_transport republish compressed in:=/raspicam_node/image/compressed raw out:=/raspicam_node/image/uncompressed
Or if you're using a launch file:
<node name="republish" type="republish" pkg="image_transport" output="screen" args="compressed in:=/raspicam_node/image/compressed raw out:=/raspicam_node/image/uncompressed" />
Then you need to change your original code to
#!/usr/bin/env python2.7
import rospy
from sensor_msgs.msg import Image
import cv2
from cv_bridge import CvBridge, CvBridgeError
rospy.init_node('opencv_example', anonymous=True)
bridge = CvBridge()
def show_image(img):
cv2.imshow("Image Window", img)
cv2.waitKey(3)
def image_callback(img_msg):
try:
cv_image = bridge.imgmsg_to_cv2(img_msg, "passthrough")
except CvBridgeError, e:
rospy.logerr("CvBridge Error: {0}".format(e))
show_image(cv_image)
sub_image = rospy.Subscriber("/raspicam_node/image/uncompressed", Image, image_callback)
cv2.namedWindow("Image Window", 1)
while not rospy.is_shutdown():
rospy.spin()

Related

Kernel restarts when compressing tif file using PIL in Anaconda

I'm trying to compress a bunch of tiff files with the pillow package. However, when I'm executing the code in python3.7.13 in Spyder IDE within the Anaconda3 environment, the Kernel restarts in the line in which the tiff file should be compressed. I tried different compression methods (e.g. "group4", "zlib", "deflate", etc..).
I also tried other packages like libtiff and tifffile, but the same problem occurs here as well.
import os
import glob
from PIL import Image, TiffTags
from IPython.display import display
import numpy as np
images = [file for file in os.listdir("C:/Home/Slicer/tif") if file.endswith('tif')]
#search for alle the images in the path
for image in images:
img_name = str(image)
img = Image.open("C:/Home/Slicer/tif/"+img_name)
print(img_name + str(img))
display(img)
#save tiff file with new name
img.save("C:/Home/Slicer/tif/" + "compressed" + img_name, compression="tiff_lzw")
Console output

I am running OpenCV for facial recognition on a Raspberry Pi with a webcam, but it has stopped working without any change in my code

I am trying to run a facial recognition service on my Raspberry Pi, but it has suddenly stopped detecting faces
I am using python-opencv for this and the last time I tested it everything worked fine. The below code is for the the training the system on new faces
`
import cv2
import os
import numpy as np
from PIL import Image
import sqlite3
recognizer = cv2.createLBPHFaceRecognizer()
detector= cv2.CascadeClassifier("haarcascade_frontalface_default.xml");
cam = cv2.VideoCapture(0)
con = sqlite3.connect('Users.db')
cur = con.cursor()
Id=raw_input('Enter your id: ')
name=raw_input('Enter your name: ')
sampleNum=0
while True:
ret, img = cam.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = detector.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
#incrementing sample number
sampleNum=sampleNum+1
#saving the captured face in the dataset folder
cv2.imwrite("dataSet/User."+Id +'.'+ str(sampleNum) + ".jpg", gray[y:y+h,x:x+w])
cv2.imshow('frame',img)
#wait for 100 miliseconds
if cv2.waitKey(100) & 0xFF == ord('q'):
break
# break if the sample number is more than 20
elif sampleNum>30:
break
cam.release()
cv2.destroyAllWindows()
def getImagesAndLabels(path):
#get the path of all the files in the folder
imagePaths=[os.path.join(path,f) for f in os.listdir(path)]
#create empth face list
faceSamples=[]
#create empty ID list
Ids=[]
#now looping through all the image paths and loading the Ids and the images
for imagePath in imagePaths:
#loading the image and converting it to gray scale
pilImage=Image.open(imagePath).convert('L')
#Now we are converting the PIL image into numpy array
imageNp=np.array(pilImage,'uint8')
#getting the Id from the image
Id=int(os.path.split(imagePath)[-1].split(".")[1])
# extract the face from the training image sample
faces=detector.detectMultiScale(imageNp)
#If a face is there then append that in the list as well as Id of it
for (x,y,w,h) in faces:
faceSamples.append(imageNp[y:y+h,x:x+w])
Ids.append(Id)
return faceSamples,Ids
os.system("sudo rm trainer/trainer.yml")
faces,Ids = getImagesAndLabels('dataSet')
recognizer.train(faces, np.array(Ids))
recognizer.save('trainer/trainer.yml')
`
Normally it would open a window and show 30 photos in succession of the user's face, but now nothing shows up after it asks for a name. I have run other OpenCV applications and it can find faces in static images.
I had to replace the haar_cascade_frontalface.xml file

Displaying PNG in matplotlib.pyplot framework in python 2.7

I am pulling PNG images from Jupyter Notebooks and manage to display with IPython.display.Image but not with matplotib.pyplot.plt. What am I missing? I use python 2.7.
I am using the following algorithm:
To open the notebook JSON content I do:
import nbformat
notebook_ = nbformat.read(file_notebook, 4)
After retrieving the relevant cell information I pull the png information from it using:
def cell_to_image(cell, out_value_item_number=1):
if "execution_count" in cell.keys(): # i.e version >=4
return cell["outputs"][out_value_item_number]['data']['image/png']
elif "prompt_number" in cell.keys(): # i.e version < 4
return cell["outputs"][out_value_item_number]['png']
return None
cell_image = cell_to_image(cell)
The first few characters of cell_image (which is unicode) looks like:
iVBORw0KGgoAAAANSUhEUgAAA64AAAFMCAYAAADLFeHSAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n
AAALEgAACxIB0t1+/AAAIABJREFUeJzs3Xd8jef/x/HXyTjZiYQkCGrU3ruR0tr9oq2qGtGo0dbe
\nm5pVlJpFUSMoVb6UoEZ/lCpatWuPUiNEEiMDmef3R75OexonJKUO3s/HI4/mXPd1X/d1f+LRR965
\n7/u6DSaTyYSIiIiIiIiIjbJ70hMQERERERERyYiCq4iIiIiIiNg0BVcRERERERGxaQquIiIiIiIi
\nYtMUXEVERERERMSmKbiKiIiIiIiITVNwFRGRxyIkJIRixYqxfv36+24/e/YsxYoVo3jx4v/yzGxb
\naGgoderUIS4uDoBdu3bRsmVLKlasyCuvvMKgQYOIjo622CcsLIyGDRtSunRp6tSpw8KFC62OW7p0
\naRo2bJju53Lnzh1GjRrFyy+/TNmyZWnRogW//fbbQ835q6++olGjRpQvX5769eszc+ZMkpOTzdtT
\nU1OZNGkSNWrUoHTp0jRp0oTdu3enGyc2NpZOn
I can easily plot in my Jupityer notebook using
from IPython.display import Image
Image(cell_image)
And now to my question:
How can I manipulate cell_image to be plt.subplot friendly?
(Assuming import matplotlib.pyplot as plt).
I realise that plt.imshow wouldn't work because this would require an array, which is not my case (which is a string, as far as I understand).
If you have your image string representation in a variable string_rep, the following code should work.
from io import BytesIO
import matplotlib.image as mpimage
import matplotlib.pyplot as plt
with BytesIO(string_rep.decode('base64')) as byte_rep:
image = mpimage.imread(byte_rep)
plt.imshow(image)

Can not Read or Play a Video in OpenCV+Python using VideoCapture

import cv2
import numpy as np
cap = cv2.VideoCapture('traffic.avi')
retval, frame = cap.read()
print retval
================ RESTART: J:\Python For DIP\traffic_video.py ================
False
>>>
The Value of retval is always False, which means the video is not read by the command. It must be True to read frames. I don't know what to do. However when I use my default webcam it turns to be True. I tried many videos and the same problem appears. Note: I have installed the ffmpeg correctly.
Note: This is not the full code, in this step I am only validating cap.read() either True or False
This method is guaranteed 100%
first of all check your version of OpenCV, say for instance 2.4.11. you can check it by typing the following commands in your Python Shell:
>>> from cv2 import __version__
>>> __version__
'2.4.11'
>>>
Then go to C:\opencv\build\x86\vc12\bin and copy opencv_ffmpeg2411.dll.
Finally go to root directory of Python ex: C:\Python27 and paste opencv_ffmpeg2411.dll in it
check the name of the file opencv_ffmpeg2411.dll, whether the version
of opencv is written or not, if not do the following
opencv_ffmpeg(version of your opencv without dots).dll
After that create a new Python file and copy this code and paste it loading your own video
import numpy as np
import cv2
# Capture video from file
cap = cv2.VideoCapture('your video')
while True:
ret, frame = cap.read()
if ret == True:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame',gray)
if cv2.waitKey(30) & 0xFF == ord('q'):
break
else:
break
cap.release()
cv2.destroyAllWindows()
you will have an output video for example like this:
Result
Finding the root directory of Python can be a little tricky. I am using an Enthought distribution and, at first, pasted the opencv_ffmpeg file into the wrong Python directory.
WRONG:
C:\Users\USERNAME\AppData\Local\Programs\Python\Python35-32
RIGHT:
C:\Users\USERNAME\AppData\Local\Enthought\Canopy\User
Long story short, make sure you find the right Python directory.

Python - fetching image from urllib and then reading EXIF data from PIL Image not working

I use the following code to fetch an image from a url in python :
import urllib
from PIL import Image
urllib.urlretrieve("http://www.gunnerkrigg.com//comics/00000001.jpg", "00000001.jpg")
filename = '00000001.jpg'
img = Image.open(filename)
exif = img._getexif()
However, this way the exif data is always "None". But when I download the image by hand and then read the EXIF data in python, the image data is not None.
I have also tried the following approach (from Downloading a picture via urllib and python):
import urllib
f = open('00000001.jpg','wb')
f.write(urllib.urlopen('http://www.gunnerkrigg.com//comics/00000001.jpg').read())
f.close()
filename = '00000001.jpg'
img = Image.open(filename)
exif = img._getexif()
But this gives me 'None' for 'exif' again. Could someone please point out what I may do to solve this problem?
Thank you!
The .jpg you are using contains no exif information. If you try the same python with an exif example from http://www.exif.org/samples/ , I think you will find it works.