I am using pydicom for extracting image data out of a dicom file. Unfortunately pydicom fails to directly extract a numpy array of data I can directly use, but I get a data string containing all values in hex (i.e. f.eks. \x03\x80\x01\x0c\xa0\x00\x02P\x00\x04#\x00\t\x80\x00\x03.... I know that the image data is encoded in a JPEG2000-format. Is there a way to reconstruct an image out of these data? I already tried via
img = Image.fromstring('RGB', len(pixelData), pixelData)
but there I get the error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/PIL/Image.py", line 2064, in fromstring
return frombytes(*args, **kw)
File "/usr/local/lib/python2.7/dist-packages/PIL/Image.py", line 2049, in frombytes
im = new(mode, size)
File "/usr/local/lib/python2.7/dist-packages/PIL/Image.py", line 2015, in new
return Image()._new(core.fill(mode, size, color))
TypeError: must be 2-item sequence, not int
Is there another way to create an image out of these data?
Second parameter (size) to Image.fromstring should be 2-tuple with height and width:
:param size: A 2-tuple, containing (width, height) in pixels.
Unfortunately pydiacom has issues with JPEG compression. Is there no way of making the images TIFF or some other uncompressed format? Is it scan data?
Related
I'm trying to load a Dataset of PNGs. The PNGs are stored in "L" mode (8bit per pixel monochrome).
When trying to convert them with image.convert('RGB'), I get the following error:
Traceback (most recent call last):
File "C:\Users\Saman\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\ImageFile.py", line 180, in load
seek = self.load_seek
AttributeError: 'PngImageFile' object has no attribute 'load_seek'
If I leave that step out and convert them to a numpy array directly with np.array(image), I get a numpy array with dtype=object and length 1, with the only Pillow Image object as its content.
Basically I followed this tutorial to stream processed video (not just retrieving frames and broadcasting) and it works for me (I'm new to html and flask). But I want to save some computation here:
I wonder if it's possible to avoid saving opencv image object to a jpeg file and then reading again? Is it a waste of computation?
I think it's even better if flask/html template could render the image by using raw 3 data channels RGB of the image.
Any idea? Thanks!
P/S: I actually tried this following code:
_, encoded_img = cv2.imencode('.jpg', img, [ int( cv2.IMWRITE_JPEG_QUALITY ), 95 ] )
But it gives the following error:
Debugging middleware caught exception in streamed response at a point where response headers were already sent.
Traceback (most recent call last):
File "/home/trungnb/virtual_envs/tf_cpu/lib/python3.5/site-packages/werkzeug/wsgi.py", line 704, in next
return self._next()
File "/home/trungnb/virtual_envs/tf_cpu/lib/python3.5/site-packages/werkzeug/wrappers.py", line 81, in _iter_encoded
for item in iterable:
File "/home/trungnb/workspace/coding/Mask_RCNN/web.py", line 25, in gen
if frame == None:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
You would want to compress it to JPEG anyway as sending the raw RGB data would be slower due to the data size.
You could try using cv::imencode to compress the image. Then you may be able send the image in a similar way to flask return image created from database
I'm trying to use Python to run OCR with pytesseract on some PowerPoint slides that have images (of text) and I'm stuck on getting the images to pass to pytesseract.
So far, I have this but that last line is the problem:
for slide in presentation.Slides:
for shape in slide.Shapes:
if 'Picture' in shape.Name: #in my case, the images I want have this.
picture_text = image_to_string(shape)
This gives an error--I guess because a PowerPoint Shape is not an image:
Traceback (most recent call last):
File "C:/Users/agent/Desktop/Chaelon Stuff on Desktop/Walpole/make_Word_rough_pass_from_PowerPoint_chapter.py", line 61, in <module>
worddoc.Content.Text = image_to_string(shape)
File "C:\Python27\lib\site-packages\pytesseract\pytesseract.py", line 143, in image_to_string
if len(image.split()) == 4:
File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 522, in __getattr__
raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: <unknown>.split
So then I tried using shape.Image but get this error:
Traceback (most recent call last):
File "C:/Users/agent/Desktop/Chaelon Stuff on Desktop/Walpole/make_Word_rough_pass_from_PowerPoint_chapter.py", line 61, in <module>
worddoc.Content.Text = image_to_string(shape.Image)
File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 522, in __getattr__
raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: <unknown>.Image
Given the image is in the presentation, I was hoping there could be some way to get each image from its Shape object and then pass each image directly to pytesseract for OCR (without having to save it to disk as an image first). Is there?
Or do I have to save it to disk as an image and then read it into pytesseract? If so, how best to do that?
You give yourself the answer to your question, but are not yet sure you are right or just don't want believe it is they way it is. Yes:
You need to save an image to disk as an image and then read it into pytesseract except you find a way to convert the image you got from PowerPoint to an image object used in PIL (Python Image Library).
Maybe someone else can provide here the information how to do the conversion from PowerPoint image to PIL image as I am not on Windows and not using Microsoft PowerPoint to test myself eventually proposed solutions, but maybe THIS link provides already enough information to satisfy your needs:
https://codereview.stackexchange.com/questions/101803/process-powerpoint-xml
Picture shapes in python-pptx have an image property, which returns an Image object:
http://python-pptx.readthedocs.io/en/latest/api/shapes.html#picture-objects
http://python-pptx.readthedocs.io/en/latest/api/image.html
The image object provides access to the image file bytes and the filename extension (e.g. "png"), which should give you what you need:
for shape in slide.Shapes:
if 'Picture' in shape.name:
picture = shape
image = picture.image
image_file_bytes = image.blob
file_extension = image.ext
# save image as file or perhaps in-memory file like StringIO() using bytes and ext.
I want to load hyperspectral data per pixel into an array and write this pixel out again using Python 3.5. I want to calculate something with the spectral information of this Pixel.
I have tried two different ways and both don't work the way I want.
First of all I have updated spectral package since the last version was stated not to work with iteratively envi.save_image but still my approach does not work.
Second my approaches both are not very good with my double for loop - I know -
If anyone could please help me on my problem.
1st:
myfile=open_image('input.hdr')
for i in range(0,myfile.shape[0]):
for j in range(0,myfile.shape[1]):
mypixel = (myfile.read_pixel(i,j))
envi.save_image('output.hdr', mypixel, dtype=np.int16)
1st example does not save the image rather gives me the error code
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.5/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 699, in runfile
execfile(filename, namespace)
File "/usr/local/lib/python3.5/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 88, in execfile
exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace)
File "/dtc/Python/Masking.py", line 132, in <module>
envi.save_image('test.hdr', mypixel, dtype=np.int16)#, metadata=myfile.metadata)
File "/usr/local/lib/python3.5/site-packages/spectral/io/envi.py", line 415, in save_image
data, metadata = _prepared_data_and_metadata(hdr_file, image, **kwargs)
File "/usr/local/lib/python3.5/site-packages/spectral/io/envi.py", line 568, in _prepared_data_and_metadata
add_image_info_to_metadata(image, metadata)
File "/usr/local/lib/python3.5/site-packages/spectral/io/envi.py", line 613, in add_image_info_to_metadata
metadata['samples'] = image.shape[1]
IndexError: tuple index out of range
2nd:
myfile=open_image('input.hdr')
envi.create_image('test.hdr',ext='.bip', interleave='bip',dtype='h',force=True,metadata=myfile.metadata)
open('test.bip', 'w').close() # empties the created file
file = open('test.bip', 'ab')#ab #opens the created file for appending the new bands
for i in range(0,myfile.shape[0]):
for j in range(0,myfile.shape[1]):
mypixel = (myfile.read_pixel(i,j))
file.write(mypixel)
file.close()
myfile.close()
The second example saves the image but stores the Pixel in a different order and messes up my image.
So this is the very short, fast and easy solution thanks to a colleague.
myfile=envi.open('input.hdr') #opens image for calculating with it
imageArray = 10000*myfile[:,:,:] #do some math with it;
#10000* is needed because input data are thresholded between {0;10000}
#and during processing get thresholded between {0;1}.
#For preventing 0 in the output with datatype int the thresholding to {0;10000} is necessary again
envi.save_image('test.hdr',imageArray,dtype=np.int16,metadata=myfile.metadata,force=True)
I have to say in advance that I am not familiar with the spectral package and envi and therefore unfortunately cannot offer a ready-to-use solution. Besides, I am not sure if I correctly understood what you are trying to do with your image.
But just some thoughts: Could the write/save function inside the for loop cause your problem, because every pixel is treated in the exact same way and it gets overwritten? I can not relate to the IndexError though.
Maybe you need a function where you can rather write a certain pixel to an empty image passing also i and j. A second option could be to save each pixel in an array and save it to an image at once after the for loop.
I'm trying to take an fft of an image in python, alter the transformed image and take a reverse fft. Specifically, I have a picture of a grid that I'd like to transform, then black out all but a central, narrow vertical slit of the transform, then take a reverse fft.
The code I'm working with now, for no alteration to transform plane:
import os
os.chdir('/Users/terra/Desktop')
import Image, numpy
i = Image.open('grid.png')
i = i.convert('L') #convert to grayscale
a = numpy.asarray(i) # a is readonly
b = abs(numpy.fft.rfft2(a))
j = Image.fromarray(b)
j.save('grid2.png')
As of now, I'm getting an error message:
Traceback (most recent call last):
File "/Users/terra/Documents/pic2.py", line 11, in
j.save('grid2.png')
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/PIL/Image.py", line 1439, in save
save_handler(self, fp, filename)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/PIL/PngImagePlugin.py", line 506, in _save
raise IOError, "cannot write mode %s as PNG" % mode
IOError: cannot write mode F as PNG
I'm very new to programming and Fourier transforms, so most related threads I've found online are over my head. Very specific help is greatly appreciated. Thanks!
The main problem is that the array contains floats after the FFT, but for it to be useful for PNG output, you need to have uint8s.
The simplest thing is to convert it to uint8 directly:
b = abs(numpy.fft.rfft2(a)).astype(numpy.uint8)
This probably will not produce the image you want, so you'll have to normalize the values in the array somehow before converting them to integers.