Search code examples
pythonopencvpython-imaging-librarydetection

Image of LED matrix to an array


I would like to read the pixels from a picture of LED matrix with the size of 96x64. They are either on or off, I provide an example picture down below.

Should I just go over the image and read the color with for example PIL or should I use anything else. I noticed that the matrix is a bit tilted and not perfectly aligned. Sometimes the small pieces it is made of are a bit shifted relative to each other.

enter image description here

EDIT:

The picture will be captured from a live stream on youtube, so it's a video. It will always be the same matrix. I am not able to have full control of the matrix and as mentioned it's a YouTube live stream of someone, I am unable to change the surroundings.


Solution

  • One approach might be to:

    • do a 4-point perspective transform to map each corner of the matrix to the corners of the image
    • scale the the result to 96x64
    • threshold

    The pixels of the image then correspond pretty well to the matrix's LEDs.

    I just did it with ImageMagick in the Terminal like this:

    magick matrix.png -distort perspective "4,10 0,0 584,7 585,0 574,383 585,387 11,388 0,387" -scale 96x64\! -threshold 30% result.png
    

    enter image description here

    That command means I want to map the point 4,10 in the input image to the point 0,0 in the output image - i.e. the top-left corner. Then I want to map the point 584,7 in the input image to the point 585,0 - i.e. the top-right corner and so on.

    If it is a video, you could improve it by looking across frames to work out where the LED centres are even if the matrix is not rectilinear. You could also optimise looking for corners, as the corner pixels will presumably illuminate at some point during the video.

    If you change the command to the following, you will get a text file with the values you want:

    magick matrix.png -distort perspective "4,10 0,0 584,7 585,0 574,383 585,387 11,388 0,387" -scale 96x64\! -threshold 30% -compress none result.pgm
    

    The P2 is a PGM header saying the file is 96x64 and the brightest value is 255. There then follow the first 4 rows of pixels:

    P2
    96 64
    255
    255 255 255 0 255 0 255 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 255 0 0 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 255 0 0 0 0 0 0 255 255 255 255 255 0 255 255 255 255 255 0 255 255 255 255 255 0 255 255 255 255 255 0 0 255 
    255 255 255 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 0 0 0 0 255 0 0 255 255 0 0 0 255 0 0 255 255 255 255 255 255 255 0 255 255 255 255 255 255 255 255 0 0 255 255 0 0 0 0 0 0 0 255 0 0 0 0 0 0 255 255 0 0 255 0 0 0 255 0 255 0 0 0 0 255 255 255 0 255 255 255 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 0 0 0 255 0 0 0 0 0 0 0 255 255 0 255 255 0 0 255 255 255 0 255 255 255 255 255 255 255 255 255 0 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 0 255 255 255 255 255 255 255 255 0 255 255 255 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 0 0 255 255 0 0 255 0 0 0 0 255 255 0 255 255 255 255 255 255 255 255 255 255 255 255 0 0 255 255 0 0 255 255 255 255 255 255 0 0 255 0 0 0 255 255 0 0 255 255 255 255 255 0 0 0 0 0 0 0 0 0 255 0 255 255 255 0 0 0 0 0 
    ...
    ...
    

    If you want a Python answer, you can either convert the code above to wand which is based on ImageMagick or do exactly the same steps in OpenCV, or with scikit-image.