I would like to import a PNG image as an 2D array or "flattened" as a vector (e.g. row of a table) in orange such that, e.g., one can use all pixel values as input for PCA or for descriptive statistics. I am aware of the image embedding but I am after the "raw" pixel values. Is there a widget for this? If not, what would be the most suitable approach to achieve this? Thanks!
1 Answer
After diving a bit deeper into Orange I found a way to do that which I'm stating here in the hope that it is useful for someone else.
My solution uses the "Python Script" widget which needs to be connected to the "Import Images" widget of the "Image Analytics" add-ons. The code of the "Python Script" widget is as follows:
import numpy as np
from PIL import Image
from pathlib import Path
from Orange.data import Table, Domain, ContinuousVariable, DiscreteVariable
print("----------------------------------------------")
print("1.", in_data.domain.metas)
assert in_data.domain.metas[1].name == 'image', "2nd entry must be the image file name"
assert in_data.domain.metas[3].name == 'width', "4th entry must be the image width"
assert in_data.domain.metas[4].name == 'height', "4th entry must be the image height"
w, h = in_data.metas[0][3], in_data.metas[0][4]
print("2. filename:", in_data.metas[0][1], "\n width, height:", w, h)
print("3.", in_data.domain)
print("4.", in_data.domain.variables)
path_to_file = Path(in_data.domain["image"].attributes["origin"])
print("path_to_file:", path_to_file)
new_data = in_data.copy()
data = []
for inst in new_data:
filename = Path(inst.metas[1])
img = Image.open(path_to_file / filename)
img_arr = np.array(img)
assert img_arr.shape == (w, h), "all images must have the same size"
data.append(img_arr.flatten())
data = np.array(data)
print(data.shape)
domain = Domain([ContinuousVariable(f"x_{i}") for i in range(w * h)])
out_data = Table.from_numpy(domain, data)
I left some of the debugging output for reference. YOu can now connect a "Data Table" widget to the "Python Script" widget. The table contains each image as a row; each column is a feature, i.e. pixel of the array.