Android Question Fast location pixel position X Y from a bitmap with only 1 pixel.

scsjc

Well-Known Member
Licensed User
Longtime User
What would be the fastest way to locate the position of a single pixel that has a bitmap image.
That bitmap image does not have any other pixels,is empty.
I've tried looping X and Y through all the pixels using bitmap.GetPixel and it's extremely slow.
 

emexes

Expert
Licensed User
BitmapCreator GetColor, or access the Buffer directly.

What is creating your bitmap image that is fully some predetermined background color, except for one pixel?

Is it definitely just one pixel, ie not splotched out over several pixels?

Is the one-pixel color known and constant? Or is it "not background"?
 
Upvote 0

scsjc

Well-Known Member
Licensed User
Longtime User
BitmapCreator GetColor, or access the Buffer directly.

What is creating your bitmap image that is fully some predetermined background color, except for one pixel?

Is it definitely just one pixel, ie not splotched out over several pixels?

Is the one-pixel color known and constant? Or is it "not background"?
It is just a blank image, with a pixel point, and I directly need to know the position of the pixel that is within a bitmap
the color pixel can see any... i put black
is only 1 pixel
 
Upvote 0

sirjo66

Well-Known Member
Licensed User
Longtime User
Can you sharing with us this image ?

A solution may be to convert the image in byte-array, and then looping through it

For example (thanks to Pooya1)
B4X:
Sub GetBytesFromBitmap(Image As Bitmap) As Byte()
    Private outStream As OutputStream
    Private Data() As Byte
   
    outStream.InitializeToBytesArray(1)
    Image.WriteToStream(outStream, 100, "PNG")
    Data = outStream.ToBytesArray
    outStream.Close
    Return Data
   
End Sub

EDIT: I'm sorry, now I see that this is for PNG format, the correct code is:
B4X:
   Dim bc As BitmapCreator
   bc.Initialize(img.Width, img.Height)
   bc.CopyPixelsFromBitmap(img)
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
What would be the fastest way to locate the position of a single pixel that has a bitmap image.

Does the single-pixel tend to be near where it last was, or does it randomly jump around the bitmap? (as in: is there likely to be any performance advantage if searching begins around the last known position of the single-pixel?)
 
Upvote 0

scsjc

Well-Known Member
Licensed User
Longtime User
Does the single-pixel tend to be near where it last was, or does it randomly jump around the bitmap? (as in: is there likely to be any performance advantage if searching begins around the last known position of the single-pixel?)
can be anywhere position. I'll explain the idea of everything to you a little......

I am currently using the perspectiveTransformation function https://www.b4x.com/android/forum/threads/perspectivetransformation.73984/#content
to adjust the perspective of a plane and obtain the value of a single POINT. That point comes to me with the perspectiveTransformation calculations in any part of the bitmap.

I need to locate the X and Y position to know the result of the perspectiveTransformation algorithm regarding a point.

To do this:

1º i create a blank image bitmap, with one pixel
2º I pass it through the perspectiveTransformation procedure
3º I get that pixel in the correct destination place within the BITMAP, but I have to know the X and Y coordinates of that pixel.
 
Upvote 0

emexes

Expert
Licensed User
I need to locate the X and Y position

Nonetheless, returning to the original mission statement:

@sirjo66 and I both think that converting the perspective-transformed bitmap to a byte array, using bitmap creator, and then scanning through that byte array directly, should be a much faster way of finding the one lit pixel.

You don't even need to check all 4 bytes of every RGBA pixel; you just need to check one of those 4 bytes that is different between the background pixels and the lit pixel, ie every 4th byte of the array.
 
Upvote 0

scsjc

Well-Known Member
Licensed User
Longtime User
I explain with some images
The problem is that I need a prospective projection to position myself in the correct position and obtain where the points are located.

In the first figure I have drawn a red and green round to give the idea of what I need. I have obtained this same first figure through perspectiveTransformation function https://www.b4x.com/android/forum/threads/perspectivetransformation.73984/#content which works with the image correctly.

The other following figures are only to give a more complete explanation.




1695560258950.png


1695560335029.png


1695560362264.png
 
Upvote 0

sirjo66

Well-Known Member
Licensed User
Longtime User
very nice,
but can you give me a real image that you need to analyze so I can do a test ??
 
Upvote 0

scsjc

Well-Known Member
Licensed User
Longtime User
very nice,
but can you give me a real image that you need to analyze so I can do a test ??
if you create a empty bitmap 1200x900 and put a dot middle ... that is a image I need get pixel

later I put a code thanks
 
Upvote 0

scsjc

Well-Known Member
Licensed User
Longtime User
I attached an example, I put a fictitious square in the image (which will not appear) and the pixel in red (it is larger than a pixel, but it is so that it can be seen well in the example)

What I need is to transform the image into a prospective one, into an image without deformation.

I found the perspectiveTransformation function and I thought that I only had to obtain the position of the pixel, and that function served me perfectly to obtain the pixel in its correct position

That's why I said about locating where the pixel is within the bitmap quickly (it will only be a pixel within the bitmap and nothing more) and I need to know the x and y coordinates

(if there is another way to calculate the position without having to do this it would be great, I am also studying some mathematical functions but they are too complex for me)
 

Attachments

  • b4aPerspectiveTransformation_andcrop.zip
    271.1 KB · Views: 52
Upvote 0

sirjo66

Well-Known Member
Licensed User
Longtime User
I did a little test.
I created an image 1200 x 900 with only one pixel black.
I runned the below code and I see that the time is 1.5 seconds for each line.
Too slow
So, we need to find a system for to convert the bitmap to an array of int
But, how ??
Now I search.......
B4X:
    Dim img As B4XBitmap = LoadBitmap(File.DirAssets, "Immagine.png")

    Log("Start...")
    Dim start As Long = DateTime.Now
    
    Dim bc As BitmapCreator
    bc.Initialize(img.Width, img.Height)
    bc.CopyPixelsFromBitmap(img)
    
    For y = 0 To bc.mHeight - 1
        Log(y & " - " & DateTime.Now)
        For x = 0 To bc.mWidth - 1
            Dim color As Int = bc.GetColor(x, y)
            If color <> -1 Then ' it is not white
                Dim elapsedTime As Long = DateTime.Now - start
                Log("Found it as position X = " & x & " and Y = " & y)
                Log("Time elaspsed = " & (elapsedTime / 1000) & " seconds")
                Exit
            End If
        Next
    Next
 
Upvote 0

sirjo66

Well-Known Member
Licensed User
Longtime User
Here is the code:
B4X:
    Dim img As B4XBitmap = LoadBitmap(File.DirAssets, "Immagine.png")

    Log("Start...")
    Dim start As Long = DateTime.Now
    
    Dim bc As BitmapCreator
    bc.Initialize(img.Width, img.Height)
    bc.CopyPixelsFromBitmap(img)

    Dim found As Boolean = False
    For y = 0 To bc.mHeight - 1
        For x = 0 To bc.mWidth - 1
            Dim color As Int = bc.GetColor(x, y)
            If color <> 0xFFFFFFFF Then ' it is not white
                Dim elapsedTime As Long = DateTime.Now - start
                Log("Found it as position X = " & x & " and Y = " & y)
                Log("Time elaspsed = " & (elapsedTime / 1000) & " seconds")
                found = True
                Exit
            End If
        Next
        If found Then Exit
    Next
 
Upvote 0

CyberDroidWare

Member
Licensed User
What would be the fastest way to locate the position of a single pixel that has a bitmap image.
That bitmap image does not have any other pixels,is empty.
I've tried looping X and Y through all the pixels using bitmap.GetPixel and it's extremely slow.
Really, it is extremely simple. Think of the 'bitmap' as a string, or simply read through the binary 4 bytes at a time after the header looking for a change, then calculate the X,Y by the index.
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
(if there is another way to calculate the position without having to do this it would be great, I am also studying some mathematical functions but they are too complex for me)

I am pretty sure that multiplying the coordinates by the perspective transformation matrix will do that.

First step is to log the transformation matrix, and some original coordinates and corresponding transformed coordinates.
 
Upvote 0

scsjc

Well-Known Member
Licensed User
Longtime User
Here is the code:
B4X:
    Dim img As B4XBitmap = LoadBitmap(File.DirAssets, "Immagine.png")

    Log("Start...")
    Dim start As Long = DateTime.Now
   
    Dim bc As BitmapCreator
    bc.Initialize(img.Width, img.Height)
    bc.CopyPixelsFromBitmap(img)

    Dim found As Boolean = False
    For y = 0 To bc.mHeight - 1
        For x = 0 To bc.mWidth - 1
            Dim color As Int = bc.GetColor(x, y)
            If color <> 0xFFFFFFFF Then ' it is not white
                Dim elapsedTime As Long = DateTime.Now - start
                Log("Found it as position X = " & x & " and Y = " & y)
                Log("Time elaspsed = " & (elapsedTime / 1000) & " seconds")
                found = True
                Exit
            End If
        Next
        If found Then Exit
    Next


The code works correctly for me to locate any pixe quickly. But in the end I decided to do something else.

I attach an example of the program to comment and see what error may be happening. The program does:

- 1st create image by going through the color palette every pixel ImageView1 and memorizes the color number and position coordinates on a MAP

- 2nd executes a correction process to re-position the original image to procesed ImageView1 tranformed in its correct place on ImageView2

- 3rd reads all the pixels, looking for the corresponding color within the map (as if it were an index) and creates a map with the relationship between the x and origin coordinates, and the x and destination coordinates of the transformed image.

It seems to work, but there is something that doesn't quite work, it seems to me that when I do the loop to show all the colors, it doesn't do it correctly and repeats colors (which then uses the same index and then creates the error)
 

Attachments

  • imagecolors.zip
    10.9 KB · Views: 47
  • Captura.JPG
    Captura.JPG
    50.5 KB · Views: 51
Upvote 0

emexes

Expert
Licensed User
It seems to work, but there is something that doesn't quite work, it seems to me that when I do the loop to show all the colors, it doesn't do it correctly and repeats colors (which then uses the same index and then creates the error)

More likely that the perspective transformation is putting pixels into the destination bitmap not precisely into destination pixel "cells" and antialiasing is smudging the color values.

24 bit color = 16 million colors. Your source image looks like it might be 220 x 220 = 48400 pixels. Try stepping the color component values by say 6 instead of 2, to give a wider color separation.

Or just do it pixel-by-pixel, one pixel on the source bitmap at a time. If it is now finding the destination pixels in milliseconds rather than seconds, and you only have to do 50000 of them, then it'll probably take less processor time than programmer time.
 
Upvote 0

emexes

Expert
Licensed User
Hang on... what you want to know is:

for any pixel (dx, dy) in the destination bitmap,
which pixel (sx, sy) it came from in the source bitmap

is this correct?
 
Upvote 0
Top