How implement an array of images in Python-opencv? - python

I am programming a code that uses 30 images and I want to put those images in an array to resize them and then use them in other functions. I was trying some things but the second loop just shows me one unique image resized 30 times.
import cv2 as cv
import glob
import numpy as np
files = glob.glob ("C:/Users/Project/imgs/*.jpg")
images = np.empty(len(files))
#This loop reads images and show rgb images
#Works OK
for i in files:
#print(myFile)
images= cv.imread(i)
cv.imshow('myFile'+str(i),images)
new = []
for i in range(30):
new = cv.resize(images,(200,266))
cv.imshow('imagen', new)
cv.waitKey(0)
cv.destroyAllWindows()

If you want to keep many elements then first create empty list and next use apppend() to add element to list.
More or less
all_images = []
for name in files:
#print(name)
image = cv.imread(name)
cv.imshow('myFile '+name, image) # you don't need `str()`
all_images.append(image)
resized_images = []
for image in all_images:
new = cv.resize(image, (200,266))
cv.imshow('imagen', new)
resized_images.append(new)
If you want to resize only first 30 images
for image in all_images[:30]:

Related

How to merge images after spliting into grids?

I'm trying to split single image into multiple grids in order to reduce dimension and do some image processing on that and then combine back splitted image to single image.
currently Im splitting single image into 72 multiple grids as shown in below code
from imutils import paths
from PIL import Image
from itertools import product
import os
source_path = r'D:\Data\images'
dest_path = r'D:\Data\cropped_data\\'
all_images = list(paths.list_images(source_path))
for img_path in all_images:
img = Image.open(img_path)
w,h = img.size
d = 500
grid = product(range(0, h-h%d, d), range(0, w-w%d, d))
file_name = img_path.split('\\')[-1].split('.')[0]
print(file_name)
save_path = dest_path+file_name
print(save_path)
os.makedirs(save_path,exist_ok=True)
for i, j in grid:
box = (j, i, j+d, i+d)
out = save_path+'\\'+'cropped'+f'_{i}_{j}'+'.jpg'
print(out)
img.crop(box).save(out)
above code snippet crop image into 72 mulitple grids and saves it in folder, I'm doing some preprocessing and saving it in same folder, I want to merge these images again back to original size in same sequence , I'm trying below code to achieve this
import glob
from PIL import Image
from itertools import product
all_images = glob.glob(r'splitted_image_folder\*.png')
d = 500
w = 6016
h = 3376
new_im = Image.new('RGB',(w,h),(250,250,250))
grid = product(range(0,h-h%d,d),range(0,w-w%d,d))
for u,(i,j) in enumerate(grid):
img = Image.open(all_images[u])
new_im.paste(img,(i,j))
new_im.save("merged_img.png","PNG")
executing this code merge only half of images at the first half of image and leaving other half in white,instead of merging all grid images it only pasting half of the images , I'm not able to understand why its missing other half .
Any guide or suggestion to achieve this will be appreciated

Extracting images from h5 file

I have images that are saved into h5 file, so now I'm wondering is it possible to extract images from h5 file in a folder? I wrote this code but it doesn't work. It save an image in folder but can't open. You can see that on the picture.
dset.h5 contains of 5 images and I need to save that images. For now I'm trying to save just one (hiking_125.jpg).
`
import h5py
import numpy as np
import cv2
save_dir = 'C:/Users.../depth'
with h5py.File('dset.h5', 'r') as hf:
IMAGE = hf['image']
print(IMAGE['hiking_125.jpg'])
print(IMAGE['hiking_125.jpg'].dtype)
#IMAGE = np.array(IMAGE)
item = []
item = np.array(IMAGE['hiking_125.jpg']).reshape(-1, 500, 600, 3)
cv2.imwrite(f"{save_dir}/.jpg", item)
cv2.imshow('Color image', item)
print(item)
`
You have a number of small errors in the code above.
This code snippet should work. It assumes dataset hf['image']['hiking_125.jpg'] is NumPy array for the image and does not need to be reshaped). Note code added to address issues displaying the image with cv.imshow().
save_dir = 'C:/Users.../depth'
with h5py.File('dset.h5', 'r') as hf:
imagename = 'hiking_125.jpg'
# get an array from the imagename dataset:
IMAGE_arr = hf['image'][imagename][()]
# create image from array
cv2.imwrite(f"{save_dir}/{imagename}", IMAGE_arr)
# post image to a window
cv2.imshow(f'Image: {imagename}', IMAGE_arr)
# keep window posted for 2500 msec
cv2.waitKey(2500)
# destroy CV2 window when done
cv2.destroyAllWindows()
You can extend the code above to export all images from dataset hf['image'] with the following. It's a small modification that uses a loop to create each file by getting the dataset names using the .keys() method.
with h5py.File('dset.h5', 'r') as hf:
image_ds = hf['image']
for imagename in image_ds.keys():
# get an array from the imagename dataset:
IMAGE_arr = image_ds[imagename][()]
# create image from array
cv2.imwrite(f"{save_dir}/{imagename}", IMAGE_arr)
# post image to a window
cv2.imshow(f'Image: {imagename}', IMAGE_arr)
# keep window posted for 2500 msec
cv2.waitKey(2500)
# destroy CV2 window when done
cv2.destroyAllWindows()

How to load images from a folder in sequence based on the number on the images name

I want to make a program to show images 1 by 1 every second based on the frame number in sequence (the images come from a video and i already change it into images .jpg with 292 frames), but there's some error that make my program to show it 1 by 1 but not in sequence, sometimes its jumped (from frame 1 to 100) and sometimes its not.
import glob
import cv2
img_location =
'E:\\User\\Programming\\Python\\Work\\asd\\*.jpg'
img_loc = sorted(glob.glob(img_location))
for img in img_loc:
print('processing %s...' % img,)
img = cv2.imread(img, 0)
cv2.imshow("img",img)
cv2.waitKey(250)
An alternative way is naming your file with the suffix 0. For example: 001, 002, ... 100, 101, ... 250
I guess you have to d0 something as follows
import glob
import cv2
import numpy as np
img_location = 'E:\\User\\Programming\\Python\\Work\\asd\\*.jpg'
img_loc = sorted(glob.glob(img_location))
img_numbers = [int(iloc.split(".")[0]) for iloc in img_loc]
sorted_indices = np.argsort(img_numbers)
for sorted_img_idx in sorted_indices:
print('processing %s...' % img_loc[sorted_img_idx],)
img = cv2.imread(img_loc[sorted_img_idx], 0)
cv2.imshow("img",img)
cv2.waitKey(250)
What this does this it assumes naming of files is as follows: 1.jpg 2.jpg and so on, we then strip the .jpg, and convert "1" to int, then we apply argsort, that returns an array of indices that correspond to a sorted array, then we just iterate through all indices and display the in sequence images
ALTERNATIVE AND EASIER WAY:
If the naming convention is as mentioned above then simply just do
base_path = 'E:\\User\\Programming\\Python\\Work\\asd\\
img_names = [ base_path + str(img_number) + ".jpg" for img_number in range(1,101)
and then iterate through it and display the images
Ffmpeg can play folder with pictures.
You can create:
cap = cv2.VideoCapture('E:\\User\\Programming\\Python\\Work\\asd\\%d.jpg', cv2.CAP_FFMPEG)
or
cap = cv2.VideoCapture('E:\\User\\Programming\\Python\\Work\\asd\\%d.jpg', cv2.CAP_IMAGES)

TypeError: too many data entries

i am trying to recreate a picture. I take a picture edging it and save it. after i made it grayscale and save it. Found the common pixels of the two images and I am trying to recreate again the picture and i get this error. It is a picture of a road and i am trying to keep only the white lanes. so after i compare the edged picture with the first picture most common pixels are the white ones that represent the lanes of the road.
The error is thrown in line marked <———-- near the end of the code listing
TypeError: too many data entries
newpic is the list in that form `[1,1,1,1,...,1]
here is my code and explaining every part. if you have any other suggestion how to achieve the result i want please say it
#LIBRARIES
import cv2
import numpy as np
import matplotlib as mpl
from matplotlib import pyplot as plt
#read and display the image
img = cv2.imread("road.jpg")
#original picture show
cv2.imshow("Window Name",img)
# edging the image
edges = cv2.Canny(img,255,255)
#show the canny picture
cv2.imshow("Window Name",edges)
#save the canny picture First argument is the file name, second
argument is the image you want to save.
cv2.imwrite('canny.png',edges)
#making the image an array
from PIL import Image
#read the pciture
img = Image.open('road.jpg').convert('LA')
#save it
img.save('greyscale.png')
#open the edited
im=Image.open("greyscale.png")
#make it an array
pix_val = list(im.getdata())
pix_val_flat = [x for sets in pix_val for x in sets]
# pix_val_flat has the pixels for out first image without edging
#print the array
#print (pix_val_flat[125]);
#get the lenght of the array
lenght=len(pix_val_flat)
#print the array
#print(lenght);
#take the canny picture and make it grayscale
edge = Image.open('canny.png').convert('LA')
#make it array
pix_val1 = list(edge.getdata())
pix_val_flat1 = [x for sets in pix_val for x in sets]
#get the lenght of the array
#lenght1=len(pix_val_flat1)
#prnt the array
#print(lenght);
#print the array
#print (pix_val_flat1[125]);
print(lenght)
newpic = [0]*lenght
lenght2=len(newpic)
print (newpic)
for c1 in range(0,lenght,3):
if pix_val_flat[c1]==pix_val_flat1[c1] and
pix_val_flat[c1+1]==pix_val_flat1[c1+1] and
pix_val_flat[c1+2]==pix_val_flat1[c1+2]:
newpic[c1]= pix_val_flat1[c1]
newpic[c1+1]= pix_val_flat1[c1+1]
newpic[c1+2]= pix_val_flat1[c1+2]
array = np.array(newpic, dtype=np.uint8)
print (array)
im2 = Image.new(im.mode, im.size)
im2.putdata (newpic) ---------------------> here i get the error
new_image = Image.fromarray(array)
new_image.save('hello.png')
cv2.waitKey(0)
cv2.destroyAllWindows()
In this case it means that your putting more data than the size you set before.
You can check the length of data you put in with len(the_list_of_data), so you'll see length gets double every time you put data (even if you overwrite). You can set the_list_of_data length to 0 and then fill it with data. This error occurs in loops too.

Loading two images at a time in a loop using Python-glob

I am trying to read all images from a folder using Python-glob.
Here is the part of code:
for file in glob.glob("\*.jpg"):
image=cv2.imread(file);
It is working pretty well, but I need to to read two images at a time in one iteration of the glob loop i.e. the two consecutive images. In simple terms i need image[i] and image[i+1].
Is this what you are looking for?
files = glob.glob("\*.jpg")
img_a = cv2.imread(files[0])
for file in files[1:]:
img_b = cv2.imread(file);
# do what you need to do with img_a and img_b
# and then prepare img_a for the next loop
img_a = img_b

Categories

Resources