I'm making live video GUI using Python and Glade-3, but I'm finding it hard to convert the Numpy array that I have into something that can be displayed in Glade. The images are in black and white with just a single value giving the brightness of each pixel. I would like to be able to draw over the images in the GUI so I don't know whether there is a specific format I should use (bitmap/pixmap etc) ?
Any help would be much appreciated!
In the end i decided to create a buffer for the pixels using:
self.pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,0,8,1280,1024)
I then set the image from the pixel buffer:
self.liveImage.set_from_pixbuf(self.pixbuf)
I think these are the steps you need:
use scipy.misc.toimage to convert your array to a PIL image
check out the answer to this question to convert your PIL image to a cairo surface
use gdk_pixbuf_get_from_surface to convert this to a pixbuf (I don't know it's name in the python api)
make a Gtk.Image out of this using Gtk.Image.new_from_pixbuf
I'm sorry it needs so many conversion steps.
Related
I want to create a basic video editing application where the user can import video clips and then use symmetry (vertical or horizontal) and offsets on their videos. How feasible is this?
For instance, consider the following image:
Right-symmetry:
Image offset to the top-left:
If that last image is confusing, basically you can think of it as the images repeating one next to the the other in a grid, infinitely, such that they're symmetric. Then, you can select a window of this grid equal to the size of the original image. Eg. the red square represents the window:
This is very feasible. Opencv can do all of this frame by frame. Although it would probably take sometime for high quality/long videos. If you want to know how to do these operations, I would open seperate questions. mirroring can for example be done by cv2.flip().
You can use the .flip () method present in the cv2 library. First enter the image with cv2.imread (path). Then to make the mirror effect you have to create a insert cv2.flip (image, 0).
Just as reported below:
image = cv2.imread(path)
mirrow = cv2.flip(image, 0)
I am trying to add two images of different sizes using bitwise operations in OpenCV using python. I want a particular point in Image1(an image of face of a person) to coincide with a particular point in Image2(image of a spectacle frame). The particular points are not the cornermost points of the images.I know the 2 mid points of the frame glasses and the pupil of the eyes. I want the frame mid points to coincide with the pupil points of the eyes in the face. The code which I am using adds the second image's leftmost corner point to the specific point of Image1 as in Line 10, whereas i want the mid point of left glass frame to be added.
The face image can be any random image and the spectacle image is as -
I am using the code:
import cv2
import numpy as np
img_frame = cv2.imread('image1.jpg',1)
img_in = cv2.imread('face.jpg',1)
new_image = np.zeros(img_frame.shape,dtype=np.uint8)
i,j,k = img_frame.shape
for ii in range (1,i):
for jj in range (1,j):
pixel = img_frame[ii,jj]
img_in[339+ii,468+jj] = pixel
cv2.imwrite('pc2_with_frame_7.jpg',img_in)
cv2.imshow('win',img_in)
cv2.waitKey(0)
cv2.destroyWindow('win')
Any kind of help would be appreciated.
Thank you.
Ok, it seems nobody else much can help so I will offer what I can...
What you are trying to do is called alpha-compositing. You can read about it here on Wikipedia and also here in the OpenCV documentation.
My tool of choice for this would be ImageMagick, which is free and has Perl, Python, C/C++ bindings as well as command-line tools. If I start with this photo (face.jpg):
and take your glasses.jpg file and convert it to a PNG with transparency, whcih looks like this:
I can run the following ImageMagick command at the Terminal
composite glasses.png face.jpg out.jpg
and I get this:
It seems that OpenCV has problems maybe with transparency, and a solution is presented here. If you want to try the masking method suggested by #ypnos in that post, I have made you the necessary input files and you can download them from my website at:
glasses.png with alpha channel
input-mask.png
I have a large 2D array (4000x3000) saved as a numpy array which I would like to display and save while keeping the ability to look at each individual pixels.
For the display part, I currently use matplotlib imshow() function which works very well.
For the saving part, it is not clear to me how I can save this figure and preserve the information contained in all 12M pixels. I tried adjusting the figure size and the resolution (dpi) of the saved image but it is not obvious which figsize/dpi settings should be used to match the resolution of the large 2D matrix displayed. Here is an example code of what I'm doing (arr is a numpy array of shape (3000,4000)):
fig = pylab.figure(figsize=(16,12))
pylab.imshow(arr,interpolation='nearest')
fig.savefig("image.png",dpi=500)
One option would be to increase the resolution of the saved image substantially to be sure all pixels will be properly recorded but this has the significant drawback of creating an image of extremely large size (at least much larger than the 4000x3000 pixels image which is all that I would really need). It also has the disadvantage that not all pixels will be of exactly the same size.
I also had a look at the Python Image Library but it is not clear to me how it could be used for this purpose, if at all.
Any help on the subject would be much appreciated!
I think I found a solution which works fairly well. I use figimage to plot the numpy array without resampling. If you're careful in the size of the figure you create, you can keep full resolution of your matrix whatever size it has.
I figured out that figimage plots a single pixel with size 0.01 inch (this number might be system dependent) so the following code will for example save the matrix with full resolution (arr is a numpy array of shape (3000,4000)):
rows = 3000
columns = 4000
fig = pylab.figure(figsize=(columns*0.01,rows*0.01))
pylab.figimage(arr,cmap=cm.jet,origin='lower')
fig.savefig("image.png")
Two issues I still have with this options:
there is no markers indicating column/row numbers making it hard to know which pixel is which besides the ones on the edges
if you decide to interactively look at the image, it is not possible to zoom in/out
A solution that also solves the above 2 issues would be terrific, if it exists.
The OpenCV library was designed for scientific analysis of images. Consequently, it doesn't "resample" images without your explicitly asking for it. To save an image:
import cv2
cv2.imwrite('image.png', arr)
where arr is your numpy array. The saved image will be the same size as your array arr.
You didn't mention the color-model that you are using. Pngs, like jpegs, are usually 8-bit per color channel. OpenCV will support up to 16-bits per channel if you request it.
Documentation on OpenCV's imwrite is here.
Using Python's PIL module, we can read an digital image into an array of integers,
from PIL import Image
from numpy import array
img = Image.open('x.jpg')
im = array(img) # im is the array representation of x.jpg
I wonder how does PIL interpret an image as an array? First I tried this
od -tu1 x.jpg
and it indeed gave a sequence of numbers, but how does PIL interpret a color image into a 3D array?
In short, my question is that I want to know how can I get a color image's array representation without using any module like PIL, how could do the job using Python?
Well, it depends on the image format I would say.
For a .jpg, there is a complete description of the format that permits to read the image .
You can read it here
What PIL does is exactly what you did at first. But then it reads the bytes following the specifications, which allow it to transform this into a human readable format (in this case an array).
It may seem complex for JPEG, but if you take png (the version without compression) everything can seem way more simple.
For example this image
If you open it, you will see something like that :
You can see several information on top that corresponds to the header.
Then you see all those zeroes, that are the numerical representation of black pixels of the image (the top left corner).
If you open the image with PIL, you will get an array that is mostly filled with 0.
If you want to know more about the first bytes, look at the png specifications chapter 11.2.2.
You will see that some of the bytes corresponds to the width and height of the image. This is how PIL is able to create the array :).
Hope this helps !
Depends on the color mode. In PIL an image is stored as a list of integers with all channels interleaved on a per-pixel basis.
To illustrate this:
Grayscale image: [pixel1, pixel2, pixel3, ...]
RGB: [pixel1_R, pixel1_G, pixel1_B, pixel2_R, pixel_2_G, ...]
Same goes for RBGA and so on.
I am trying to increase the height of an image using PIL but I don't want the image to be resized; I actually want a strip of blank pixels at the bottom of the image. Any way of doing this with PIL?
I guess one way would be to make a new image of the required size and copy the old image into it but I can't seem to find the right function to do this.
Oops, just realized you can do image.crop() and it will resize the image for you.