B4J Question Is it possible to check the difference of object/bytes ?

Magma

Expert
Licensed User
Longtime User
Hi there...

is it possible in b4j to check how different is a bytes[] from another bytes[] ?
Probably in percentage...

lets say we have these two strings before we change them to bytes...

1. GEORGE
2. GIORGO

That seems 50% the same... and 50% different

Now imagine you have two images with 200000bytes... check the difference.... (some will tell with AI, but if you wanna check it pixel by pixel - but fast ?)

is there ready something like it ?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
B4X:
Sub AppStart (Args() As String)
    Log(CalcDifference("GEORGE".GetBytes("utf8"), "GIORGO".GetBytes("utf8")))
End Sub

Private Sub CalcDifference(b1() As Byte, b2() As Byte) As Float
    Dim small() As Byte = IIf(b1.Length < b2.Length, b1, b2)
    Dim large() As Byte = IIf(b1.Length < b2.Length, b2, b1)
    Dim SameCount As Int
    For i = 0 To large.Length - 1
        If i < small.Length And small(i) = large(i) Then SameCount = SameCount + 1
    Next
    Return SameCount / large.Length
End Sub

I think that this algorithm is quite meaningless but you haven't provided enough context...
 
Upvote 0

Sandman

Expert
Licensed User
Longtime User
If I ignore your requirement for bytes, it seems you're looking for something to calculate the Levenshtein distance between two strings.

Information about it

As a curiosity, this is the command (not the algorithm) for it in PHP

The Wikipedia page contains pseudocode for the algorithm, if this is something you want to implement yourself. Of course, you might be more temped to use one of the available implementations instead.
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
If I ignore your requirement for bytes, it seems you're looking for something to calculate the Levenshtein distance between two strings.

Information about it

As a curiosity, this is the command (not the algorithm) for it in PHP

The Wikipedia page contains pseudocode for the algorithm, if this is something you want to implement yourself. Of course, you might be more temped to use one of the available implementations instead.
wow!

Yes.. "is" one part of those I need...

@Erel Ofcourse this is the standard a loop at bytes or string and a check between the same position...

and generally I understand that is not the same comparing "Apples" and "Oranges" (different images...)

But I need a start... may be if I am more specific...
I have two screenshots for example 1920x1080 and in the second i have 10 pixels different color....
i know that i can check...

B4X:
    for w=0 to 1919
        for h=0 to 1079
            if firstpic.pset(w,h)=secondpic.pset(w,h) then o=o+1
        next h
    next w

    perc=o/(1920*1080)
    log(perc*100)

But this will be slow... so is there faster way ?
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
For my RAviaMQTT (Remote Administration VIA MQTT)

already have some compression and a way to use little bandwidth... and works pretty good...
but I want to filter.. pictures... that seems to be same with 99%~100%.. to not send them... ...ofcourse I will send every some ms... but when not big changes... i will bypass them.
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
found that...
 
Upvote 0

Sandman

Expert
Licensed User
Longtime User
Sounds like you sort of want what you describe, but not really. You probably want a description of the differences between picture A and picture B. And then just send that diff to the receiver.
 
Upvote 0

kimstudio

Active Member
Licensed User
Longtime User
But this will be slow... so is there faster way ?

This should be fast as it is the simplest image processing method... the key is to have fast raw access to all pixels like what Erel did for BitmapCreator.

As every pixel will be looped so it can't be simplified, however, it can be done in parrallel way. Many OpenCV functions support parrallel computing if processing has no pixel order dependencies. It is easier in C++ but I don't know how to do that in B4X. If call OpenCV from B4X then may also have Image<->Mat conversion overhead I assume.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
You are probably going to have to iterate the images yourself. However you might be able to reduce the iterations needed by, assuming you are using BitmapCreator, converting the image byte arrays to long arrays using my ByteConverter library then instead of needing
1920 x 1080 = 2,073,600 loops and comparisons
you would do 16 times fewer
480 x 270 = 129,600 loops and comparisons
Whether this would be fast enough for your use only trying it would tell.
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
Just in case, if what you wanted is to get differences from consecutive camera input frames in order to detect movement or whatever, you'll need to take into account that, although 2 frames may 'look' the same, they will possibly have many differences in their pixel values due to noise and light changes. So, direct pixel comparison will not work in this case.

(Seen this later)
already have some compression and a way to use little bandwidth... and works pretty good...
but I want to filter.. pictures... that seems to be same with 99%~100%.. to not send them... ...ofcourse I will send every some ms... but when not big changes... i will bypass them.
Inthis case all the mentioned loop methods will be ok. But I bet that OpenCV should be fast enough specially for large images. There are Core functions to add, substract, and count non-zero values in a Mat which are really optimized.
Also, you'll possibly need a way to know which areas (i.e., the boundings) have changed (or have a number of changes above a given threshold) and when only local changes occur just send that sub-picture along with its coordinates. It will be more efficient than sending the whole picture again.
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
Just in case, if what you wanted is to get differences from consecutive camera input frames in order to detect movement or whatever, you'll need to take into account that, although 2 frames may 'look' the same, they will possibly have many differences in their pixel values due to noise and light changes. So, direct pixel comparison will not work in this case.

(Seen this later)

Inthis case all the mentioned loop methods will be ok. But I bet that OpenCV should be fast enough specially for large images. There are Core functions to add, substract, and count non-zero values in a Mat which are really optimized.
Also, you'll possibly need a way to know which areas (i.e., the boundings) have changed (or have a number of changes above a given threshold) and when only local changes occur just send that sub-picture along with its coordinates. It will be more efficient than sending the whole picture again.
Is there any example ?
A suggestion .. with b4x code?
 
Upvote 0
Top