Converting numpy list of images to mp4 video - image

I have Numpy list of 1000 RGB images (1000, 96, 96, 3). I have used openCV to create a mp4 video out of these images. my road is brown and car is red but after I create the video they turned blue.
Could you please tell me how could I avoid this problem?
My code:
img_array = []
for img in brown_dataset:
img_array.append(img)
size = (96,96)
out = cv2.VideoWriter('project_brown.mp4',cv2.VideoWriter_fourcc(*'DIVX'),15, size)
for i in range(len(img_array)):
out.write(img_array[i])
out.release()
Before video:
After video:

As mentioned in the comments , OpenCV uses BGR format by default, where your input dataset is RGB.
Here is one way to fix it
img_array = []
for img in brown_dataset:
img_array.append(img)
size = (96,96)
out = cv2.VideoWriter('project_brown.mp4',cv2.VideoWriter_fourcc(*'DIVX'),15, size)
for i in range(len(img_array)):
rgb_img = cv2.cvtColor(img_array[i], cv2.COLOR_RGB2BGR)
out.write(rgb_img)
out.release()

Related

Converting Images to Numpy arrays with correct dimension

I am trying to convert 100 images into a numpy array, which in turn will be fed into my neural network.
My NN is training data was a 4D numpy array (No of Images, 32, 32, 3).
When using below code to read images and feed into model.predict() i am getting following error.
"Error when checking input: expected conv2d_input to have 4 dimensions, but got array with shape (100, )"
This is the code i have written:
'''new_data = []
files = glob.glob (r"load images")
for myFile in files:
#print(myFile)
image = cv2.imread(myFile)
new_data.append(np.asarray(image))
#new_data = np.array(new_data)
print('new_data shape:', np.array(new_data).shape)'''
Output is "new_data shape: (100,)"
I am expecting new_data dimention to be (100, 32, 32, 3). Please help on how to achieve this.
Thanks,
Mrinal
Thanks for all the response.The issue was that images were not of same size. After i resized them all to 32*32 and did a np.reshape().
Below is the revised code
files = glob.glob (r"files\*.png*")
for myFile in files:
image = cv2.imread(myFile)
img = cv2.resize(image , (32 , 32)) # Reshaping the testing images to 32*32
new_data.append(img)
new_data = np.reshape(new_data, (len(new_data),32,32,3))
you can directly use PILLOW library for this
from PIL import Image
from numpy import asarray
image = Image.open('kolala.jpeg')
# convert image to numpy array
data = asarray(image)
print(type(data))
print(data.shape)
image2 = Image.fromarray(data)
print(type(image2))

Reading & Writing Grayscale TIF files in Matlab

I'm trying to extract a (very) large number of subimages from a large grayscale TIF file and save each image as a GIF, PNG, or even another TIF using MATLAB. I'm able to display the individual images using imshow(sub(:,:,1),cmap) but when I try to write the data to an image file, the generated files are just white squares 101x101 px. Using the cmap argument in imwrite produces the same result, as does changing the image format (I've tried with PNG, TIF, GIF, and JPG with no luck). The file a.tif is 16 bit according to the property menu in Windows Explorer. Any help is appreciated. I'm really at wit's end with this.
% Import coordinates array and correct for multiplication by 10
datafile = 'data.xlsx';
coords = xlsread(datafile,1,'G2:H13057');
x = coords(:,1) ./ 10;
y = coords(:,2) ./ 10;
r = 50;
[img, cmap] = imread('a.tif'); % import the image
s = 2*r+1; % scalar of size of each submatrix in the array (sise of image)
sub = zeros(s,s,num); % create 3D matrix/array of matrices. Each submatrix corresponds to 50 px box around each point
i = 1:4;
subrgb = zeros(s,s,num);
for i=1:4
sub(:,:,i) = img((y(i)-r):(y(i)+r),(x(i)-r):(x(i)+r));
filename = 'dot_%d.png';
filename = sprintf(filename,i);
imwrite(sub(:,:,i),filename,'png');
end
Try changing the line:
sub = zeros(s,s,num);
to:
sub = zeros(s,s,num,class(img));
I assume that the problem is that sub is of type double.
Good luck

Add padding to object in 4-channel image

I have a 4-channel image (.png, .tif) like this one:
I am using OpenCV, and I would like to add padding of type BORDER_REFLECT around the flower. copyMakeBorder is not useful, since it adds padding to the edges of the image.
I can add certain padding if I split the image in bgr + alpha and apply dilate with BORDER_REFLECT option on the bgr image, but that solution spoils all the pixels of the flower.
Is there any way to perform a selective BORDER_REFLECT padding addition on a ROI defined by a binary mask?
EDIT:
The result I expect is something like (sorry I painted it very quickly with GIMP) :
I painted two black lines to delimit the old & new contour of the flower after the padding, but of course those lines should not appear in the final result. The padding region (inside the two black lines) must be composed by mirrored pixels from the flower (I painted it yellow to make it understandable).
A simple python script to resize the image and copy the original over the enlarged one will do the trick.
import cv2
img = cv2.imread('border_reflect.png', cv2.IMREAD_UNCHANGED)
pad = 20
sh = img.shape
sh_pad = (sh[0]+pad, sh[1]+pad)
imgpad = cv2.resize(img, sh_pad)
imgpad[20:20+sh[0], 20:20+sh[1], :][img[:,:,3]==255] = img[img[:,:,3]==255]
cv2.imwrite("padded_image.png", imgpad)
Here is the result
But that doesn't look very 'centered'. So I modified the code to detect and account for the offsets while copying.
import cv2
img = cv2.imread('border_reflect.png', cv2.IMREAD_UNCHANGED)
pad = 20
sh = img.shape
sh_pad = (sh[0]+pad, sh[1]+pad)
imgpad = cv2.resize(img, sh_pad)
def get_roi(img):
cimg = img[:,:,3].copy()
contours,hierarchy = cv2.findContours(cimg,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#Remove the tiny pixel noises that get detected as contours
contours = [cnt for cnt in contours if cv2.contourArea(cnt) > 10]
x,y,w,h = cv2.boundingRect(cnt)
roi=img[y:y+h,x:x+w]
return roi
roi = get_roi(img)
roi2 = get_roi(imgpad)
sh = roi.shape
sh2 = roi2.shape
o = ((sh2[0]-sh[0])/2, (sh2[1]-sh[1])/2)
roi2[o[0]:o[0]+sh[0], o[1]:o[1]+sh[1], :][roi[:,:,3]==255] = roi[roi[:,:,3]==255]
cv2.imwrite("padded_image.png", imgpad)
Looks much better now
The issue has been already addressed and solved here:
http://answers.opencv.org/question/90229/add-padding-to-object-in-4-channel-image/

From raw bits to jpeg without writing into a file

I have a real time application which receives jpg images coded in base64. I do not know how to show the image in matlab without having to save the image in the disk and open it afterwards.
This is the code I have so far, that saves the image in the disk before showing it:
raw = base64decode(imageBase64, '', 'java');
fid = fopen('buffer.jpg', 'wb');
fwrite(fid, raw, 'uint8');
fclose(fid);
I = imread('buffer.jpg');
imshow(I);
Thanks!
You can do it with the help of Java. Example:
% get a stream of bytes representing an endcoded JPEG image
% (in your case you have this by decoding the base64 string)
fid = fopen('test.jpg', 'rb');
b = fread(fid, Inf, '*uint8');
fclose(fid);
% decode image stream using Java
jImg = javax.imageio.ImageIO.read(java.io.ByteArrayInputStream(b));
h = jImg.getHeight;
w = jImg.getWidth;
% convert Java Image to MATLAB image
p = reshape(typecast(jImg.getData.getDataStorage, 'uint8'), [3,w,h]);
img = cat(3, ...
transpose(reshape(p(3,:,:), [w,h])), ...
transpose(reshape(p(2,:,:), [w,h])), ...
transpose(reshape(p(1,:,:), [w,h])));
% check results against directly reading the image using IMREAD
img2 = imread('test.jpg');
assert(isequal(img,img2))
The first part of decoding the JPEG byte stream is based on this answer:
JPEG decoding when data is given in array
The last part converting Java images to MATLAB was based on this solution page:
How can I convert a "Java Image" object into a MATLAB image matrix?
That last part could also be re-written as:
p = typecast(jImg.getData.getDataStorage, 'uint8');
img = permute(reshape(p, [3 w h]), [3 2 1]);
img = img(:,:,[3 2 1]);
imshow(img)

Is it possible to have black and white and color image on same window by using opencv?

Is it possible to have black-and-white and color image on same window by using opencv libraray? How can I have both of these images on same window?
fraxel's answer has solved the problem with old cv interface. I would like to show it using cv2 interface, just to understand how this easy in new cv2 module. (May be it would be helpful for future visitors). Below is the code:
import cv2
import numpy as np
im = cv2.imread('kick.jpg')
img = cv2.imread('kick.jpg',0)
# Convert grayscale image to 3-channel image,so that they can be stacked together
imgc = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
both = np.hstack((im,imgc))
cv2.imshow('imgc',both)
cv2.waitKey(0)
cv2.destroyAllWindows()
And below is the output I got:
Yes it is, here is an example, expaination in the comments:
import cv
#open color and b/w images
im = cv.LoadImageM('1_tree_small.jpg')
im2 = cv.LoadImageM('1_tree_small.jpg',cv.CV_LOAD_IMAGE_GRAYSCALE)
#set up our output and b/w in rgb space arrays:
bw = cv.CreateImage((im.width,im.height), cv.IPL_DEPTH_8U, 3)
new = cv.CreateImage((im.width*2,im.height), cv.IPL_DEPTH_8U, 3)
#create a b/w image in rgb space
cv.Merge(im2, im2, im2, None, bw)
#set up and add the color image to the left half of our output image
cv.SetImageROI(new, (0,0,im.width,im.height))
cv.Add(new, im, new)
#set up and add the b/w image to the right half of output image
cv.SetImageROI(new, (im.width,0,im.width,im.height))
cv.Add(new, bw, new)
cv.ResetImageROI(new)
cv.ShowImage('double', new)
cv.SaveImage('double.jpg', new)
cv.WaitKey(0)
Its in python, but easy to convert to whatever..
Small improvement to the code with modern writing
concatenate
instead of
hstack
that is discontinued (stack can also be used)
import cv2
import numpy as np
im = cv2.imread('kick.jpg')
img = cv2.imread('kick.jpg',0)
# Convert grayscale image to 3-channel image,so that they can be stacked together
imgc = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
both = np.concatenate((im,imgc), axis=1) #1 : horz, 0 : Vert.
cv2.imshow('imgc',both)
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
img = cv2.imread("image.jpg" , cv2.IMREAD_GRAYSCALE)
cv2.imshow("my image",img)
cv2.waitkey(0)
cv2.destroyAllWindow
#The image file should be in the application folder.
#The output file will be 'my image' name.
#The bottom line is to free up memory.

Resources