Convert a black and white image to array of numbers?

16,052

Solution 1

I would recommend to read in images with opencv. The biggest advantage of opencv is that it supports multiple image formats and it automatically transforms the image into a numpy array. For example:

import cv2
import numpy as np

img_path = '/YOUR/PATH/IMAGE.png'
img = cv2.imread(img_path, 0) # read image as grayscale. Set second parameter to 1 if rgb is required 

Now img is a numpy array with values between 0 - 255. By default 0 equals black and 255 equals white. To change this you can use the opencv built in function bitwise_not:

img_reverted= cv2.bitwise_not(img)

We can now scale the array with:

new_img = img_reverted / 255.0  // now all values are ranging from 0 to 1, where white equlas 0.0 and black equals 1.0 

Solution 2

Load the image and then just invert and divide by 255.

Here is the image ('Untitled.png') that I used for this example: https://ufile.io/h8ncw

import numpy as np
import cv2
import matplotlib.pyplot as plt

my_img = cv2.imread('Untitled.png') 
inverted_img = (255.0 - my_img)  
final = inverted_img / 255.0

# Visualize the result
plt.imshow(final)
plt.show()

print(final.shape)
(661, 667, 3)

Results (final object represented as image):

final image

Share:
16,052

Related videos on Youtube

SamTheGoodOne
Author by

SamTheGoodOne

Updated on September 15, 2022

Comments

  • SamTheGoodOne
    SamTheGoodOne about 1 year

    The image is 28 pixels by 28 pixels. They can interpret this as a big array of numbers: Like the image above suggests, how can I convert the image to the left into an array that represent the darkness of the image between 0 for white and decimals for darker colours closer to 1? as shown in the image usingpython 3`?

    Update: I have tried to work abit more on this. There are good answers below too.

    # Load image 
    filename = tf.constant("one.png")
    image_file = tf.read_file(filename)
    
    # Show Image
    Image("one.png")
    
    #convert method
    def convertRgbToWeight(rgbArray):
        arrayWithPixelWeight = []
        for i in range(int(rgbArray.size / rgbArray[0].size)):
            for j in range(int(rgbArray[0].size / 3)):
                lum = 255-((rgbArray[i][j][0]+rgbArray[i][j][1]+rgbArray[i][j][2])/3) # Reversed luminosity
                arrayWithPixelWeight.append(lum/255) # Map values from range 0-255 to 0-1
    
        return arrayWithPixelWeight
    
    
    
    # Convert image to numbers and print them
    image_decoded_png = tf.image.decode_png(image_file,channels=3)
    image_as_float32 = tf.cast(image_decoded_png, tf.float32)
    
    numpy.set_printoptions(threshold=numpy.nan)
    sess = tf.Session()
    squeezedArray = sess.run(image_as_float32)
    
    convertedList = convertRgbToWeight(squeezedArray)
    
    print(convertedList) # This will give me an array of numbers. 
    
    • Rahul Bohare
      Rahul Bohare over 5 years
      @SamTheGoodOne Just curious about why you would do simple Image processing task such as this with TensorFlow. Much easier with cv/NumPy.
    • Reti43
      Reti43 over 5 years
      Your question after the edit is more unfocused. Before you were asking how to do something. Now you're also asking if your way is okay. Why? Do you get an incorrect result? Does it seem verbose or inefficient? What are your criteria for choosing what is an acceptable answer?
  • Reti43
    Reti43 over 5 years
    It would help if you fleshed out your answer a bit more, i.e., by explaining or showing how to normalise the array. It'd make it more complete, as someone who doesn't know what that means would have to resort to third-party sources to learn. You should also point out that 0 refers to black and white to 255, since the questions seems to want white = 0 and black = 1.
  • Rahul Bohare
    Rahul Bohare over 5 years
    This would result in white pixels having the value of 1, whereas the question wants 1 for black pixels.
  • Rahul Bohare
    Rahul Bohare over 5 years
    This would result in white pixels having the value of 1, whereas the question wants 1 for black pixels.
  • seralouk
    seralouk over 5 years
    see again my answer.
  • seralouk
    seralouk over 5 years
    Why downvoting? any explanation? it's my answer exact ?
  • Rahul Bohare
    Rahul Bohare over 5 years
    I actually upvoted your answer. Makes perfect sense to me. Eludes me why someone would downvote it.
  • seralouk
    seralouk over 5 years
    Me too. Especially when they don't leave a comment to explain why. Thanks mate
  • SamTheGoodOne
    SamTheGoodOne over 5 years
    Can you please see my answer. I have updated the question with a possible answer. Please comment if this is also a possible way to do it with tensorflow
  • SamTheGoodOne
    SamTheGoodOne over 5 years
    Can you please see my answer. I have updated the question with a possible answer. Please comment if this is also a possible way to do it with tensorflow.
  • SamTheGoodOne
    SamTheGoodOne over 5 years
    Can you please see my answer. I have updated the question with a possible answer. Please comment if this is also a possible way to do it with tensorflow
  • Tim
    Tim over 5 years
    @SamTheGoodOne for me, without testing, your code seems reasonable. But as you probably noticed it is much harder to do the image processing with tensorflow. That's why i highly recommend the usage of opencv. It makes your life much easier ;)
  • Reti43
    Reti43 over 5 years
    In my opinion this is the correct answer to the original question as stated. I would have written it myself, but Daniel got there first with the idea, so I left him a comment to flesh it out a bit more. My only suggestion is that plotting the result distracts from the answer as it's more about getting float numbers and the plot will have inverted colours anyway.