Cannot identify image file io.BytesIO on raspberry Pi using PiCamera library and PIL - raspberry-pi

I am having trouble using the output from PiCamera capture function (directed in a BytesIO stream) and opening it using the PIL library. Here is the code (based on the PiCamera basic examples):
#Camera stuff
camera = PiCamera()
camera.resolution = (640, 480)
stream = io.BytesIO()
sleep(2)
try:
for frame in camera.capture_continuous(stream, format = "jpeg", use_video_port = True):
frame.seek(0)
image = Image.open(frame) //THIS IS WHERE IS CRASHES
#OTHER STUFF THAT IS NON IMPORTANT GOES HERE
frame.truncate(0)
finally:
camera.close()
stream.close()
The error is : PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0xaa01cf00>
Any help would be greatly appreciated :)
Have a nice day!

The problem is simple but I am wondering why the io library works that way.
One simply needs to seek back the stream to 0 after truncating it or seek to 0 and then simply call truncate with no parameter (all after you are done opening the image). Like so:
for frame in camera.capture_continuous(stream, format = "jpeg", use_video_port = True):
stream.seek(0)
image = Image.open(stream)
#Do stuff with image
stream.seek(0)
stream.truncate()
Basically when you open the image and do some operation on it, the pointer of the BytesIO can move around and end up somewhere else than the zero position. After that when you call truncate(0) it does not move the pointer back to zero as I thought it would (seems logical to me to move the pointer back to where the truncation occurs). When to code runs once more, the capture writes in the stream but this time it does not start writing at the beginning and everything breaks after that.
Hope this can help someone in the future :)

Related

Qt Save form take 3-4 second to open

i'm using this on push button click in Qt:
QString fileName = QFileDialog::getSaveFileName(this, tr("Save file"),
QString(),
tr("(*.csv));
it take 3-4 second to open the save Form. why? how i can improve speed?
Try to connect this slot to a QPushButton:
void MainWindow::openFD(){
QTime myopentime=QTime::currentTime();
for (int i=0;i<1000000;i++) ;//comment out this line for the real test
QString fileName = QFileDialog::getSaveFileName(this,QString(),QString(myopentime.toString("m.s.zzz")+" "+QTime::currentTime().toString("m.s.zzz"))
,tr("*.csv") );
}
Then try to run it with and without the count part.
You will see, that the count part adds some ms... without it there is not even ms (mili-second) of difference in the time shown in filename place.
So, you have to search somewhere else in your code or give us a better example.
PS:
1) You will need :
#include <QTime>
2) The line that counting is there to show you that my method works (since you will see some difference when uncomment)
Result and Answer: The problem is not on QFileDialog if this test will not give you differences but somewhere else in your code or possibly in the Window manager of your OS.

Blank output for image subtraction when using raspicam library

I am using raspberry pi with raspicam to run a project. I have downloaded the raspicam library from http://sourceforge.net/projects/raspicam/files/?
I am trying to run a code for image subtraction but not getting results. Here is my code
raspicam::RaspiCam_Cv Camera;
Camera.set(cv::CAP_PROP_FRAME, CV_8UC1);
if(!Camera.open())
{
std::cerr<<"cannot open camera"<<std::endl;
}
Camera.grab();
Camera.retrieve(frame1);
Camera.grab();
Camera.retrieve(frame2);
Camera.grab();
Camera.retrieve(frame3);
while (True)
{
frame1=frame2;
frame2=frame3;
Camera.grab();
Camera.retrieve(frame3);
absdiff(frame2,frame1,d1);
imshow("result1",d1);
absdiff(frame2,frame3,d2);
imshow("result2",d2);
}
when I run this code I get blank frames of result1 and result2 as output. This is just a part of my code ignore if i have missed something.
Well, inside your loop
frame1=frame2;
...
absdiff(frame2,frame1,d1);
that'll be sort of identically zero...
Also, have you considered the timing here? You're grabbing images very close together in the time-domain, so naturally they'll be mostly identical (bar noise and fast motion) so the difference will be near-zero.
Cheers,

PIL to Qimage conversion: QImage constructor does not free memory

I am developping a Qt application loading pictures with PIL, modifying colors and alpha channels, then converting them as QImage.
Here is the problematic piece of code: normal repeated usage of the ImageQt function: # memory is filled around 7 mB/s
if name == 'main':
while True:
im = Image.open('einstein.png') #small picture
imQt = QtGui.QImage(ImageQt.ImageQt(im)) # convert to PySide.QtGui.QImage
imQt.save('outtest.png')# -> rendered picture is correct
#del(imQt) and del(im) does not change anything
time.sleep(0.02)
The problem here is the crazy memory filling, when the picture is supposed to be erased by the garbage collector. I checked with gc.collect(), but it did not change anything.
This example shows what happends with the imageQt function, but in fact, I noticed this is a problem caused by QImage: if you repeatedly use the QImage constructor with data, the memory used by python process increases: im= Image.load('mypic.png').convert('RGBA')
data = im.toString('raw','RGBA')
qIm = QtGui.QImage(data,im.size[0],im.size[1],QtGui.QImage.Format_ARGB32)
qIm.save('myConvertedPic.png')# -> picture is perfect
If you put this code in a loop, memory will increase, as 1st example. From there i am a bit lost because this is a PySide problem...
I tried to use a workaround, but it does not work either:
#Workaround, but not working ....
if name == 'main':
while True:
im = Image.open('einstein.png') #small picture
imRGBA = im.convert('RGBA') # convert to RGBA
imRGBA.save('convtest.png') # ->picture is looks perfect
imBytes = imRGBA.tostring('raw','RGBA')
#print("size %d %d" % (imRGBA.size[0],imRGBA.size[1]))
qImage = QtGui.QImage(imRGBA.size[0],imRGBA.size[1],QtGui.QImage.Format_ARGB32) # create new empty picture
qImage.fill(QtCore.Qt.blue) # fill with blue, otherwise it catches pieces of the picture still in memory
loaded = qImage.loadFromData(imBytes,'RGBA') # load from raw data
print("success %d" % loaded)# -> returns 0
qImage.save('outtest.png')# -> rendered picture is blue
time.sleep(0.02)
I am really stuck here, if you could help find a solution with this workaround ? Because I'm really stuck here!
Also I would like to discuss the QImage problem. Is there any reliable way to free this memory ? Could the fact I am using python3.2(32bits) be a problem in this case ? Am I the only one in this case ?
The imports I am using in case of:
import time
import sys
import PySide
sys.modules['PyQt4'] = PySide # this little hack allows to solve naming problem when using PIL with Pyside (instead of PyQt4)
from PIL import Image, ImageQt
from PySide import QtCore,QtGui
After further unsuccessful searching, I noticed, that the PIL function image.tostring() associated with a QImage constructor caused this problem
im = Image.open('einstein.png').convert('RGBA')
data = im.tostring('raw','RGBA') # the tostring() function is out of the loop
while True:
imQt = QtGui.QImage(data,im.size[0],im.size[1],QtGui.QImage.Format_ARGB32)
#imQt.save("testpic.png") #image is valid
time.sleep(0.01)
#no memory problem !I think I am really close to find what is wrong, but I cannot point it out.
It definitely has something to do with the data variable being held in memory.

Specifying timeout when reading URL image with MATLAB imread function

The MATLAB imread function provides the ability to read an image from a URL. This generally works OK, but occasionally I encounter an image that takes a very long time to respond.
For instance, at the time of posting the following URL appears to just be stuck in a 'connecting...' state for over 5 minutes before finally succeeding.
http://www.hollywoodheadache.com/wp-content/uploads/2007/12/tom-and-julia.jpg
Is there any way I can set a timeout within MATLAB?
Thanks
I don't know how to interrupt imread with a timer object. Besides, I suspect about its possibility. But I may recommend you to check whether you can access to the file first, and then, you get the file. I have written the following function to check the file and internet status:
function flag = does_url_exist(urlName)
url =java.net.URL(urlName);
try
link = openStream(url);
parse = java.io.InputStreamReader(link);
snip = java.io.BufferedReader(parse);
if ~isempty(snip)
flag = 1;
else
flag = 0;
end
catch exception
flag = 0;
end
end
Then it is as follows:
fname = 'http://www.hollywoodheadache.com/wp-content/uploads/2007/12/tom-and-julia.jpg';
if(does_url_exist(fname))
img = imread(fname);
end
Note that for internet connection checking, I took the initial code from this post. Also note that if you are sure that the file exists, it is not efficient to check it again since it increases the running time.

Matlab: Writing avi file

I am having a problem when creating an avi file using Matlab. My aim is to use an edge filter on an entire video and save the file as an avi. The filter works fine, my problem is the writing of the avi file.
My code:
vidFile = VideoReader('video.avi');
edgeMov = avifile('edges','fps',30);
for i = 1:vidFile.numberofframes
frameI = read(vidFile,i);
frameIgray = rgb2gray(frameI);
edgeI = edge(frameIgray,'canny',0.6);
edgeIuint8 = im2uint8(edgeI);
edgeIuint8(:,:,2) = edgeIuint8(:,:,1);
edgeIuint8(:,:,3) = edgeIuint8(:,:,1);
edgeMov = addframe(edgeMov,edgeIuint8);
end
edgeMov = close(edgeMov)
When the loop finishes and the avifile is closed, I go to play the video and it says "Windows Media Player encountered a problem while playing this file". I've also tried, without success, Media Player Classic and VLC which lead me to believe that the problem must be the file itself. Using GSpot I checked the file and it said that the AVI header is corrupt.
Retrying the loop again returned exactly the same problem. What's confusing me is when I run the loop for a smaller number of frames, 30 for example, the video writes fine and I can watch it. The size of the video I am trying to convert is in excess of 1000 frames so I don't know if size is a problem?
Any help would be greatly appreciated, thank you.
I've used the following to create AVI
edgeMov = avifile('video.avi','compression','Indeo5','fps',15,'quality',95);
Give it a try.