Reputation: 111
I am trying to convert an image to a numpy array and save it as a text/csv file. I am then trying to load the contents of the text/csv file back into an image.
In the whole process, the dimension, datatype pixel values must not change in order to reconstruct the original image accurately (without distortions).
What I have so far-
testim = cv2.imread('img.jpg') #reading the input image
numpyimg = np.array(testim) # Saving as a numpy array
# Checking the shape and image
cv2_imshow(numpyimg)
print(numpyimg.shape)
# Trying to save in csv
for i in numpyimg:
np.savetxt(fname="image_array.csv", delimiter=",", X=i)
# Check generated csv file after loading it
image_array = np.loadtxt(
fname="image_array.csv", delimiter=","
)
print("NumPy array: \n", image_array)
print("Shape: ", image_array.shape)
print("Data Type: ", image_array.dtype.name)
When I print the contents of the saved file what I see -
NumPy array that I could saved in a file:
[[ 70. 176. 153.]
[ 63. 170. 144.]
[ 57. 167. 139.]
...
[ 69. 118. 80.]
[ 67. 117. 77.]
[ 64. 114. 74.]]
Shape: (1040, 3)
The array of the original image though-
array([[[ 78, 120, 165],
[ 63, 105, 150],
[ 48, 91, 134],
...,
[ 22, 80, 51],
[ 35, 91, 62],
[ 49, 105, 76]],
[[ 77, 122, 160],
[ 62, 109, 147],
[ 50, 95, 132],
...,
[ 24, 84, 54],
[ 29, 87, 58],
[ 38, 96, 67]],
[[ 73, 124, 150],
[ 66, 120, 143],
[ 63, 116, 137],
...,
[ 28, 90, 60],
[ 26, 86, 56],
[ 27, 87, 57]],
...,
[ 69, 118, 80],
[ 67, 117, 77],
[ 64, 114, 74]]], dtype=uint8)
shape: (780, 1040, 3)
These don't look to be the same and I fail to understand what is going wrong.
Is there an easier and more accurate way to go about this?
I have been stuck on this for a long time. Any help is appreciated!
Upvotes: 2
Views: 3559
Reputation:
The size of your CSV file = (1040, 3).
The size of your original image = (780, 1040, 3).
You could try this:
from PIL import Image
import numpy as np
#numpy array from image
img = np.array(Image.open('1.jpg')) # img to a numpy array shape = (50, 100, 3)
img_reshaped = img.reshape(img.shape[0], -1) # instead of looping and slicing through channels shape = (50, 300)
np.savetxt('img_2_numpy.csv', img_reshaped, delimiter=',') # save it as numpy array in csv file
numpydata = np.loadtxt('img_2_numpy.csv',dtype='uint8', delimiter=',') # load an array from csv file
array3D = numpydata.reshape(numpydata.shape[0], numpydata.shape[1] // img.shape[2], img.shape[2]) # reshape to (50, 100, 3)
# image from numpyarray
im = Image.fromarray(array3D)
im.show()
Upvotes: 1
Reputation: 111
I was able to figure the solution out after a lot of trial and error. This is what helped me solve my problem-
from PIL import Image
# Create an empty text file before this step
with open('image_array.txt', 'w') as outfile:
for slice_2d in numpyimg:
np.savetxt(outfile, slice_2d)
new_data = np.loadtxt('image_array.txt')
new_data=new_data.reshape((780,1040,3))
img = Image.fromarray(new_data.astype(np.uint8),'RGB')
img.save('try.jpg')
img.show()
Upvotes: 2
Reputation: 36360
These don't look to be the same and I fail to understand what is going wrong.
For representing color image OpenCV
uses three-dimensional array. To access single value you have to provide 3: Y-cordinate, X-cordinate, which color channel (0
for Blue, 1
for Green, 2
for Red if I remember OpenCV convention correctly).
text/csv
is well suited for representing 2D data (think about spreadsheet), but if you wish more dimensions this require special treating before writing and after reading.
RFC4180 does not provide any features relating to type of content of columns.
Upvotes: 1