Python: Merge 2 binary file into one file without read them - python

I've two binary files containing rgb pixes values. I would like to merge these two files into one big file.
I did this first:
img1 = np.fromfile("img1.rgb",dtype=np.uint8)
img2 = np.fromfile("img2.rgb",dtype=np.uint8)
img1 = np.reshape(img1,(1024,10000,3))
img2 = np.reshape(img2,(1024,10000,3))
out = np.empty((1024,20000,3))
out[:,:10000] = img1
out[:,-10000:] = img2
out.flatten().tofile("out.rgb")
The problem is that I load in memory the 2 images and also the resulting merge image.
Is it possible to do this without loading the images into memory ?
Maybe by using numpy memmap?

Related

What input format does m2stitch.stitch_images() require?

I'm trying to stitch some microscope images with the help of the m2stitch library.
The only example on how to use it is in the docs: https://m2stitch.readthedocs.io/en/latest/usage.html
Unfortunatelly, I cannot figure out what format my input needs to be in. In the example, it loads a bunch of .npy images from a directory directly with np.load(). I cannot get this to work due to some other permission issues.
I can however transform the images i want to stitch to .npy files.
My code:
import numpy as np
import pandas as pd
import m2stitch
image1 = np.load(r'A61_20230123113809.npy')
image2 = np.load(r'A62_20230123113809.npy')
image3 = np.load(r'A63_20230123113809.npy')
image4 = np.load(r'A64_20230123113809.npy')
images = np.array(image1, image2, image3, image4)
rows = [0,1]
cols = [0,1]
result_df, _ = m2stitch.stitch_images(images, rows, cols, row_col_transpose=False)
The line that I cannot get to work to give me the correct format is this:
images = np.array(image1, image2, image3, image4)
Any idea what format of "images" is needed for "stitch_images" to work?

Overlay more than two images using PIL python

Hi i am using the below code to merge more than one image using PIL module
from PIL import Image
img0 = Image.open("w1.png")
img0 = img0.convert('RGBA')
img1 = Image.open("body.png")
img1 = img1.convert('RGBA')
img0.paste(img1, (0,0), img1)
img0.save('0.png')
img2 = Image.open("0.png")
img2 = img2.convert('RGBA')
img3 = Image.open("d1.png")
img3 = img3.convert('RGBA')
img2.paste(img3, (0,0), img3)
img2.show()
would like to know if there is way i can merge more than two images.
i have 8 images that i need to merge.
Thank you for any suggestion.
would like to know if there is way i can merge more than two images. i have 8 images that i need to merge.
Just... keep paste-ing new images on?
All Image.paste does is merge the parameter image onto the subject, you can keep doing that, and it'll keep merging the new images.
if you want to merge img,I suggesting a tool called stegsolve
There is a download url:
https://github.com/eugenekolo/sec-tools/tree/master/stego/stegsolve/stegsolve
There is usage:

Merging images from different folders and storing to a different folder

I have three different folders m1, m2, and m3. The 'm1' folder contains images of the format image(i)_m1.png (where i =1 to N), 'm2' folder contains images of the format image(i)_m2.png, and 'm3' folder contains images of the format image(i)_m3.png. I want to merge these images using cv2.merge like this:(cv2.merge((image1_m1, image1_m2, image1_m3)) and it continues for N times and get stored in a different folder than contains 'N' merged images of the format image(i)_merged.png.
import pandas as pd
import cv2
import numpy as np
import glob
import os
filenames1 = glob.glob("data_folder/m1/*.png")
filenames1.sort()
filenames2 = glob.glob("data_folder/m2/*.png")
filenames2.sort()
filenames3 = glob.glob("data_folder/m3/*.png")
filenames3.sort()
for f1 in filenames1:
for f2 in filenames2:
for f3 in filenames3:
img1 = cv2.imread(f1)
img2 = cv2.imread(f2)
img3 = cv2.imread(f3)
img_m1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
img_m2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
img_m3 = cv2.cvtColor(img3, cv2.COLOR_BGR2GRAY)
img_rgb = cv2.merge((img_m1, img_m2, img_m3))
cv2.imwrite("data_folder/merge/img_name.png", img_rgb)
Your question is not complete. I assume you have a problem with for loop.
You might replace the nested for loops with this:
for f1,f2,f3 in zip(filenames1,filenames2,filenames3):

Combine more than 1 openCV images and show them in CV2.Imshow() in OpenCV Python

I am having 3 to 4 images and I am trying to combine them all into one image (put into one window) and then show them through CV2.imshow() function. But the problem is that every solution to this problem is for exactly the same dimension images, which is not my case. My images are all of different dimensions. Kindly help me out how to solve this problem? I have four images with different dimension and want output like this
|||||||||||||||||||||||||||||||||
|| Image1 || Image2 ||
||||||||||||||||||||||||||||||||||
|| Image1 || Image2 ||
||||||||||||||||||||||||||||||||||
Currently, I have code like this for two images which work on only equally sized Images
im = cv2.imread('1.png')
img = cv2.imread('2.jpg')
both = np.hstack((im,im))
cv2.imshow('imgc',both)
cv2.waitKey(10000)
Use im.resize() function of opencv to resize the image and then do the combining task.
Always use a reference dimension such as 1000 x 800 (you can change it)
import cv2
import numpy as np
list_of_img_paths = [path2,path3,path4]
im = cv2.imread(path1)
imstack = cv2.resize(im,(1000,800))
for path in list_of_img_paths:
im = cv2.imread(path)
im = cv2.resize(im,(1000,800))
# hstack to join image horizontally
imstack = np.hstack((imstack,im))
cv2.imshow('stack',imstack)
cv2.waitKey(0)

Create Numpy array of images

I have some (950) 150x150x3 .jpg image files that I want to read into an Numpy array.
Following is my code:
X_data = []
files = glob.glob ("*.jpg")
for myFile in files:
image = cv2.imread (myFile)
X_data.append (image)
print('X_data shape:', np.array(X_data).shape)
The output is (950, 150). Please let me know why the list is not getting converted to np.array correctly and whether there is a better way to create the array of images.
Of what I have read, appending to numpy arrays is easier done through python lists and then converting them to arrays.
EDIT: Some more information (if it helps), image.shape returns (150,150,3) correctly.
I tested your code. It works fine for me with output
('X_data shape:', (4, 617, 1021, 3))
however, all images were exactly the same dimension.
When I add another image with different extents I have this output:
('X_data shape:', (5,))
So I'd recommend checking the sizes and the same number of channels (as in are really all images coloured images)? Also you should check if either all images (or none) have alpha channels (see #Gughan Ravikumar's comment)
If only the number of channels vary (i.e. some images are grey), then force loading all into the color format with:
image = cv2.imread (myFile, cv2.IMREAD_COLOR)
EDIT:
I used the very code from the question, only replaced with a directory of mine (and "*.PNG"):
import cv2
import glob
import numpy as np
X_data = []
files = glob.glob ("C:/Users/xxx/Desktop/asdf/*.PNG")
for myFile in files:
print(myFile)
image = cv2.imread (myFile)
X_data.append (image)
print('X_data shape:', np.array(X_data).shape)
Appending images in a list and then converting it into a numpy array, is not working for me. I have a large dataset and RAM gets crashed every time I attempt it. Rather I append the numpy array, but this has its own cons. Appending into list and then converting into np array is space complex, but appending a numpy array is time complex. If you are patient enough, this will take care of RAM crasing problems.
def imagetensor(imagedir):
for i, im in tqdm(enumerate(os.listdir(imagedir))):
image= Image.open(im)
image= image.convert('HSV')
if i == 0:
images= np.expand_dims(np.array(image, dtype= float)/255, axis= 0)
else:
image= np.expand_dims(np.array(image, dtype= float)/255, axis= 0)
images= np.append(images, image, axis= 0)
return images
I am looking for better implementations that can take care of both space and time. Please comment if someone has a better idea.
Here is a solution for images that have certain special Unicode characters, or if we are working with PNGs with a transparency layer, which are two cases that I had to handle with my dataset. In addition, if there are any images that aren't of the desired resolution, they will not be added to the Numpy array. This uses the Pillow package instead of cv2.
resolution = 150
import glob
import numpy as np
from PIL import Image
X_data = []
files = glob.glob(r"D:\Pictures\*.png")
for my_file in files:
print(my_file)
image = Image.open(my_file).convert('RGB')
image = np.array(image)
if image is None or image.shape != (resolution, resolution, 3):
print(f'This image is bad: {myFile} {image.shape if image is not None else "None"}')
else:
X_data.append(image)
print('X_data shape:', np.array(X_data).shape)
# If you have 950 150x150 images, this would print 'X_data shape: (950, 150, 150, 3)'
If you aren't using Python 3.6+, you can replace the r-string with a regular string (except with \\ instead of \, if you're using Windows), and the f-string with regular string interpolation.
Your definition for the .JPG frame that will be put into a matrix of the same size should should be x, y, R, G, B, A. "A" is not used, but it does take up 8 bits at the end of each pixel.

Categories

Resources