Changing image size while capturing using webcam using imageio - python

I am trying to capture image with each function call
import imageio as iio
camera = iio.get_reader("<video0>")
screenshot = camera.get_data(0)
plt.imsave(filename, screenshot)
camera.close()
I am able to save the image but the image size is varying sometime it is of the size of 960540 and sometime 1280720.
I went through the documentation of imageio but did not find any attribute to set its shape. I want a fix shape of image all the time.
I have tried OpenCV, it has its own limitation w.r.t my requirements.
So please suggest something in this package only.
Could anyone please help.

Your comment made clear you want to keep the resolution consistent for the duration of the whole video. As imageio does not provide a resize operation I suggest you to use skimage to handle that part.
import imageio as iio
import matplotlib.pyplot as plt
from skimage.transform import resize
camera = iio.get_reader("<video0>")
filename = "experiment_"
# randomly set to 30 frames for this example
for i in range(0, 30):
screenshot = camera.get_data(i)
# skimage resize function here
screenshot = resize(screenshot, (1280, 720))
final_filename = str(i) + ".jpg"
plt.imsave(filename+final_filename, screenshot)
camera.close()

Related

Information about image

How can I get the information about image? I need file size (bytes), image size (pixels), color
mode, bits per pixel. I've already found image size (pixels) but I can't find another.
I have:
from skimage.io import imread
im = imread('abc.png')
print("Size: ", im.size, im.shape)
I recommend using the Pillow library.
This will give you all the requested information about the image except the file size.
from PIL import Image
im = Image.open('whatever.png')
width, height = im.size
Refer to this link for the attributes for the image object
In order to get the file size use this snippet below.
import os
print os.stat('somefile.ext').st_size

cv2.imshow command doesn't work propley . Shows incomplete image

I am able to open the image but my image is not completely visible in the window . I mean it shows me cropped version of the image im using. It would be great if you can help me visualize the complete image shown through cv2.imshow().I am using the visual studio and below is the code:
import numpy as np
import cv2
Org_img=cv2.imread('coins.png',1)
img=cv2.imread('coins.png',0)
cv2.imshow('image',img)
cv2.imshow('image2',Org_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
The image is probably larger than the screen, use the resize function to adjust for the desired output, also take a look on the shape for checking these values and window flags in the second link.
import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg')
res = cv.resize(img,None,fx=factor, fy=factor, interpolation = cv.INTER_CUBIC)
If factor > 1.0 the image is getting larger than the original and if factor < 1.0 you are reducing the image (factor = 0.5 will divide by 2), fx and fy can be different values.
See geometric transformations
Window flags

PIL image to array and back

EDIT: Sorry, the first version of the code was bullshit, I tried to remove useless information and made a mistake. Problem stays the same, but now it's the code I actually used
I think my problem is probably very basic but I cant find a solution. I basically just wanted to play around with PIL and convert an image to an array and backward, then save the image. It should look the same, right? In my case the new image is just gibberish, it seems to have some structure but it is not a picture of a plane like it should be:
def array_image_save(array, image_path ='plane_2.bmp'):
image = Image.fromarray(array, 'RGB')
image.save(image_path)
print("Saved image: {}".format(image_path))
im = Image.open('plane.bmp').convert('L')
w,h = im.size
array_image_save(np.array(list(im.getdata())).reshape((w,h)))
Not entirely sure what you are trying to achieve but if you just want to transform the image to a numpy array and back, the following works:
from PIL import Image
import numpy as np
def array_image_save(array, image_path ='plane_2.bmp'):
image = Image.fromarray(array)
image.save(image_path)
print("Saved image: {}".format(image_path))
im = Image.open('plane.bmp')
array_image_save(np.array(im))
You can just pass a PIL image to np.array and it takes care of the proper shaping. The reason you get distorted data is because you convert the pil image to greyscale (.convert('L')) but then try to save it as RGB.

python3.5 PIL Image not displaying image

The following code does not display the image lists.jpg (in current dir):
print(dir(Image)) displays components; im.size, im.filename, im.format all return correct values.
What have I not done to display this jpg file?
from PIL import Image
im = Image.open("lists.jpg")
im.show() # did not work - perhaps due to the environment Jupyter Notebooks
Solution: replaced module with another with immediate results.
from IPython.display import Image
Image(filename='lists.jpg')
I know it is quite late to post but I will do it for new readers.
This problem arises in case of Jupyter Notebooks. Using show() does not display the image. So discard calling show() like in the code below. This will display the image in the output of the cell.
from PIL import Image
im = Image.open("lists.jpg")
im
To display the image on screen:
from PIL import Image
im = Image.open("lists.jpg")
im.show()
See also http://pillow.readthedocs.io/en/4.0.x/reference/Image.html

Python OpenCV drawing errors after manipulating array with numpy

I'm reading in an image with OpenCV, and trying to do something with it in numpy (rotate 90deg). Viewing the result with imshow from matplotlib, it all seems to be working just fine - image is rotated. I can't use drawing methods from OpenCV on the new image, however. In the following code (I'm running this in a sagemath cloud worksheet):
%python
import cv2
import matplotlib.pyplot as plt
import numpy as np
import os, sys
image = np.array( cv2.imread('imagename.png') )
plt.imshow(image,cmap='gray')
image = np.array(np.rot90(image,3) ) # put it right side up
plt.imshow(image,cmap='gray')
cv2.rectangle(image,(0,0),(100,100),(255,0,0),2)
plt.imshow(image,cmap='gray')
I get the following error on the cv2.rectangle() command:
TypeError: Layout of the output array img is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)
The error goes away if I use np.array(np.rot90(image,4) ) instead (i.e. rotate it 360). So it appears that the change in dimensions is messing it up. Does OpenCV store the dimensions somewhere internally that I need to update or something?
EDIT: Adding image = image.copy() after rot90() solved the problem. See rayryeng's answer below.
This is apparently a bug in the Python OpenCV wrapper. If you look at this question here: np.rot90() corrupts an opencv image, apparently doing a rotation that doesn't result back in the original dimensions corrupts the image and the OP in that post experiences the same error you are having. FWIW, I also experienced the same bug.... no idea why.
A way around this is to make a copy of the image after you rotate, and then show the image. This I can't really explain, but it seems to work. Also, make sure you call plt.show() at the end of your code to show the image:
import cv2
import matplotlib.pyplot as plt
import numpy as np
import os, sys
image = np.array( cv2.imread('imagename.png') )
plt.imshow(image,cmap='gray')
image = np.array(np.rot90(image,3) ) # put it right side up
image = image.copy() # Change
plt.imshow(image,cmap='gray')
cv2.rectangle(image,(0,0),(100,100),(255,0,0),2)
plt.imshow(image,cmap='gray')
plt.show() # Show image
I faced the same problem with numpy 1.11.2 and opencv 3.3.0. Not sure why, but this did the job for me.
Before using cv2.rectangle, add the line below:
image1 = image1.transpose((1,0)).astype(np.uint8).copy()
Reference
Convert data type works for my problem.
The image is of type np.int64 before the convert.
image = image.astype(np.int32) # convert data type

Categories

Resources