convert image into pixel dataframe into csv file using python - python

i have folder with pictures ("C:\Users\Admin\Downloads\mypicture")
here example of it
8
and2
i want convert it to pixel dataframe like this
pixel1 pixel. pixel158 pixel159 pixel160 pixel161 pixel162 pixel163 pixel164 pixel165 pixel166 pixel167 pixel168 pixel169 pixel170 pixel171 pixel172
1 0 … 0 191 250 253 93 0 0 0 0 0 0 0 0 0 0
2 0 … 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0
pixel173 pixel174 pixel175 pixel176
1 0 0 0 0
2 0 0 16 179
Every image is represented as a single row . The greyscale of each image falls in the range [0, 255].
i do so
img = mpimg.imread("C:\Users\Admin\Downloads\mypicture")
img = np.ravel(img)
df = pd.DataFrame([img])
but i get this error
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape
How can i get desired data frame in csv file?

You could Use PIL library to convert the image to a pixel dataframe, by getting the pixel's list from an image like this
from PIL import Image
im = Image.open('image.png')
pixels = list(im.getdata())
this will return a list of pixels with the (r,g,b) values, so if you just want to get the grayscale of each pixel, just iterate the list in the second element of each value, like this
result = []
counter = 0
for pixel in pixels:
counter += 1
result.append(['pixel'+ str(counter), pixel[1]])
return (result)
Output:
['pixel1', 72], ['pixel2', 50], ['pixel3', 0], ['pixel4', 11], ['pixel5', 30], ['pixel6', 42], ['pixel7', 107], ['pixel8', 123], ['pixel9', 124], ['pixel10', 130]

Related

Rasterio grayscale .tif image is empty

I'm facing an issue when opening a .tif using rasterio using the code below.
fp = 'image.tif'
image = rasterio.open(fp)
print(image.read())
When printing the content of the image, I get this
[[[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
...
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]]]
I verified all values and they are all 0. However, when dragging the image in QGIS, I can view it and confirm that the image contains values ranging from 101 to 122.
QGIS image
Any idea on how to read the image and get these 101 to 122 values as a numpy array ?
Here's a link to the image in question

Scikit Image load binary image and convert to binary matrix

I have created a numpy array shape(11 x 11) with all pixels 0 excluding one column filled with 1.
[[ 0 0 0 0 0 1 0 0 0 0 0 ]
[ 0 0 0 0 0 1 0 0 0 0 0 ]
[ 0 0 0 0 0 1 0 0 0 0 0 ]
[ 0 0 0 0 0 1 0 0 0 0 0 ]
[ 0 0 0 0 0 1 0 0 0 0 0 ]
[ 0 0 0 0 0 1 0 0 0 0 0 ]
[ 0 0 0 0 0 1 0 0 0 0 0 ]
[ 0 0 0 0 0 1 0 0 0 0 0 ]
[ 0 0 0 0 0 1 0 0 0 0 0 ]
[ 0 0 0 0 0 1 0 0 0 0 0 ]
[ 0 0 0 0 0 1 0 0 0 0 0 ]]
The array was saved as a png image using matplotlib.imsave yielding the expected image - black background with a white line in the middle.
When trying to reimport the saved png image
skipy.imread and Pil.Image.Open yield an array of the form
[[[ 68 1 84 255]
[ 68 1 84 255]
[ 68 1 84 255]
[ 68 1 84 255]
[ 68 1 84 255]
[253 231 36 255]
[ 68 1 84 255]
[ 68 1 84 255]
[ 68 1 84 255]
[ 68 1 84 255]
[ 68 1 84 255]]
...
]
What does this file format mean (could not find an explanation in the scikit image documentation) ?
And how do I convert it back to the binary input image?
What you see is explained thusly:
your data was grayscale
then you plotted that with a colormap
-- the line looks yellow and the background looks dark blue/violet?
then you told matplotlib to save that false-color picture
then you read that false-color picture back
now you have RGBA pixel data. you see the first pixel row, and each value of each color pixel
If you wanted to maintain the grayscale appearance of your data, you'd have some choices.
Use plt.imshow(arr, cmap="gray"), which uses a gray color map rather than a colorful one.
When reading the image, and also converting any color to grayscale, you can choose scikit-image or OpenCV. OpenCV has cv.imread(fname, cv.IMREAD_GRAYSCALE). scikit-image offers skimage.io.imread(fname, as_gray=True).
And really you should use scikit-image or OpenCV for writing your picture in the first place. Matplotlib is for plotting, not for storing data authentically. Matplotlib took your data and rescaled it so the maximum and minimum value become 0 and 1, which is black and white for the gray cmap.
On grayscale, a pixel with value 1 doesn't appear white - this simply happens because matplotlib normalizes the image before displaying it.
Choose either:
a) Keep the original binary values, then the saved image won't have a white line in the middle
b) Have a white line in the middle, but then you'll have to modify the array before saving and after loading it.
Ad b)
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
# This is the array you have
arr = np.zeros((11, 11), dtype=np.uint8)
arr[:, 5] = 1
plt.figure()
plt.imshow(arr, cmap='gray')
plt.show()
# This will ensure that the line appears white in the .png
arr_png = arr * 255 # 2**8 - 1
# Write to disk
cv.imwrite('line.png', arr_png)
# Load from disk
arr_from_disk = np.array(cv.imread('line.png', 0), dtype=np.uint8)
# Rescale
arr_from_disk = np.divide(arr_from_disk, 255)
assert np.array_equal(arr, arr_from_disk), 'Oops'

Converting numpy array into an RGB image using PILLOW

I have a numpy array of dimension 11*11 that I want to convert into an RGB image so I'm using this code :
import matplotlib.pyplot as plt
from PIL import Image as im
n_images = 1
train_data_np = train_data.to_numpy()
train_images = train_data_np[:n_images]
for i in range(n_images):
image_train = np.reshape(train_images[i], [11, 11])
image = im.fromarray(np.uint8(image_train))
plt.imshow(image)
plt.show()
My problem is that the image displayed is not all RGB because for this value :
[[ 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 255 0 0 150 25 43 7 43 0]
[ 0 0 12 0 0 255 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 255 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 255 0]]
it displayed this image
which doesn't respect RGB format as you can see where 0 it should be black instead
of purple and 255 should be white instead of yellow.
I tried to convert the numpy array of [11,11] into [11,11,3] to support RGB channels but it gave in the end a grayscale image only white and black. but it is not what I want. Here is the code that I used :
n_images = 1
train_data_np = train_data.to_numpy()
train_images = train_data_np[:n_images]
for i in range(n_images):
image_res = np.reshape(train_images[i],[11,11])
img2 = np.zeros( ( image_res.shape[0], image_res.shape[1], 3 ) )
img2[:,:,0] = image_res # same value in each channel
img2[:,:,1] = image_res
img2[:,:,2] = image_res
image_train = np.reshape(img2,[11,11,3])
image = im.fromarray(np.uint8(image_train),'RGB')
plt.imshow(image)
plt.show()
can someone explain to me how to implement or use a python function to transform the NumPy array 11x11 into an array of 11x11x3 using a colormap ?
This link contains an example of what i want really to do :
https://www.mathworks.com/help/matlab/ref/ind2rgb.html
Thank you in advance

outputs the number of pixels for each color in the image using numpy [duplicate]

This question already has an answer here:
How to count RGB or HSV channel combination in an image?
(1 answer)
Closed 2 years ago.
I need to output the number of pixels from an image
Hello guys, I need a hand to output the total number of pixels by color. I am new to image processing with Numpy and Numpy array. I know I need to have knowledge of it when I am dealing with individual pixel in image. I try to look for more resources about obtaining pixels value with Numpy. I couldn't find any helpful to my situation.Please help me. I am eager to learn more. Any documentation or blog post or books. Any comments highly appreciated.
I am trying to print like this:
red : ????? pixels
green : ??????? pixels
blue : ??? pixels
-------------------------
the image shape is (1536, 2048, 3)
I have tried this code
from PIL import Image
import numpy as np
img_path = "sample.png"
with Image.open(img_path) as im:
data = np.array(im)
red, green, blue = data[:, :, 0], data[:, :, 1], data[:, :, 2]
print(red, green, blue)
But it given me something like this
[[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
...
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]] [[255 255 255 ... 255 255 255]
[255 255 255 ... 255 255 255]
[255 255 255 ... 255 255 255]
...
[255 255 255 ... 255 255 255]
[255 255 255 ... 255 255 255]
[255 255 255 ... 255 255 255]] [[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
...
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]]
You could add this at the end.
print(np.count_nonzero(red))
print(np.count_nonzero(green))
print(np.count_nonzero(blue))
EDIT:
If you don't use single channel colors you could do something like this:
from PIL import Image
import numpy as np
img_path = "sample.png"
colors = {}
with Image.open(img_path) as im:
data = np.array(im)
for row in data:
for pixel in row:
color = '{}_{}_{}'.format(*pixel)
colors[color] = colors.get(color, 0)
colors[color] += 1
for color, count in colors.items():
print(color, count)
You can use np.count_nonzero, reducing along the two first axes, which will give you a count of pixels across the channels:
np.count_nonzero(im, axis=(0,1))
For instance:
from sklearn.datasets import load_sample_images
im = load_sample_images()['images'][0]
np.count_nonzero(im, axis=(0,1))
# array([272366, 272418, 268717], dtype=int64)

Error when transforming numpy array to PIL Image

I have a variable img which is a int64 numpy.array with sizes 28x28. Its content looks like this:
[...]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 68 154 188 176 254 254 254 254 254
227 106 17 0 0 0 0 0 0 0]
[...]
I want to convert the array to a PIL image. To do so I call img = Image.fromarray(img, mode='L') but the output I get is only 0s while it is obvious that it shouldn't be like that. I have checked the mode options and seems like L is correct. Also checked other answers inside stackoverflow and couldn't find something that reproduces this particular problem.
L (8-bit pixels, black and white)
Why is this "simple" piece of code given an unexpected behaviour?
Thanks in advance!
As #Divakar pointed out, the data types were not coherent.
Just by adding np.uint8() it works:
img = Image.fromarray(np.uint8(img), mode='L')

Categories

Resources