Megan Darcy
Megan Darcy

Reputation: 582

How to extract (x, y) coordinates from image and write to CSV file?

I need to extract the (x, y) coordinates from a given image file using Python.

I want the data to be in the following format

pixel#   x    y  
1        0    0  
2        1    0  
.  
. 
301      0    1  
302      1    1  
.  
.  
XX,000   299 199  

for any size of image file I have.

Currently I am using this script:

from PIL import Image
import numpy as np 
import sys

# load the original image
img_file = Image.open("inputimage_005004.jpg") 
img_file.show() 

# get original image parameters...
width, height = img_file.size
format = img_file.format
mode = img_file.mode

# Make image Greyscale
img_grey = img_file.convert('L') 
img_grey.save('result.jpg')
img_grey.show()
value = np.asarray(img_grey.getdata(),dtype=img_grey.float64).reshape((img_grey.size[1],img_grey.size[0]))
np.savetxt("outputdata.csv", value, delimiter=',')

However I am getting an error at the 2nd last line where

value = np.asarray(...)

The error is:

AttributeError: 'Image' object has no attribute 'float64`

Also, I would like the output to be similar to the one in this StackOverflow question:

Extract x,y coordinates of each pixel from an image in Python .

How can I combine my current script with the above link and fix my present error?


EDIT:

The error is fixed, but I am not getting the (x, y) coordinates of the image file correctly. It gives me a very long number like this:

2.270000000000000000e+02,2.370000000000000000e+02,2.270000000000000000e+02,2.320000000000000000e+02,2.330000000000000000e+02,...

But, I would like it to be in the format as shown above. How can I achieve this?

Upvotes: 0

Views: 3800

Answers (2)

HansHirse
HansHirse

Reputation: 18925

You can use this answer from the linked Q&A pretty much as-is. For the proper printing of the integers in the CSV file, you need to set the fmt parameter in np.savetxt accordingly. If you explicitly want to have the pixel numbers in front, just add another column counting from 1 to number of pixels.

That'd be my solution here:

from PIL import Image
import numpy as np

img_grey = Image.open('path/to/your/image.png').convert('L')
print(img_grey.size)
# (300, 241)

# Taken from: https://stackoverflow.com/a/60783743/11089932
xy_coords = np.flip(np.column_stack(np.where(np.array(img_grey) >= 0)), axis=1)

# Add pixel numbers in front
pixel_numbers = np.expand_dims(np.arange(1, xy_coords.shape[0] + 1), axis=1)
value = np.hstack([pixel_numbers, xy_coords])
print(value)
# [[    1     0     0]
#  [    2     1     0]
#  [    3     2     0]
#  ...
#  [72298   297   240]
#  [72299   298   240]
#  [72300   299   240]]

# Properly save as CSV
np.savetxt("outputdata.csv", value, delimiter='\t', fmt='%4d')
----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.19041-SP0
Python:        3.9.1
PyCharm:       2021.1.1
NumPy:         1.19.5
Pillow:        8.2.0
----------------------------------------

Upvotes: 1

Chiebukar
Chiebukar

Reputation: 93

Image_gray is an image object. Such objects don't have float data type attributes. You should pass a numpy data type attribute to the dtype argument. You could pass np.float32, np.float64 e.t.c since you want to change the pixels from integers to decimal values. You could also pass them as strings like 'float32', 'float64' Check out the documentation here https://numpy.org/devdocs/user/basics.types.html

Upvotes: 0

Related Questions