News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

A question of logic

Started by guga, July 23, 2018, 04:50:11 AM

Previous topic - Next topic

guga

Hi guys

How can we determine the number of a value biased on the properties of some expressions ? (This is to try to solve a algorithm for pixel manipulation, but i want to know the logic of this math before trying to apply)

For example...let´s say we have 2 numbers(pixels)...each one of them have the range from 0 to 255
Value1 = 10
Value2 = 100

Where Value2 cannot be bigger then 76.5 and the resultant value of Value2 must be smaller then 10 (Value1)

How to reduce the value2 proportionally without truncating it ?

I 1st though in finding the delta of both and then do this:

Ratio1Max = 255/10 = 25.5 ===> From pixel 1 we have a max value of 10 which is 25.5 times smaller then the original range
Ratio2Max = 255/76.5 = 3.333333333333333333333333333333333333333333333333333333333 ===> From pixel 2 we have a max value of 76.5 which is 3.333.. times bigger then the original range
NewPixel2 = Value*Ratio2Max = 100*3,3333 = 333,3333 ; This is the value of pixel2 if the original scale (0 to 255) allowed it
Ratio2 = 333,333/255 = 1.307189542483660130718954248366013071895424836601307189542

So, pixel2 is 30,7189% bigger as if the ratio would be from 1 to 255 (instead 1 to 76.5), therefore, we must reduce 30,71% of it since we reached the limit.
NewPixel2 = 255-30,7189% = 176.666805 ----> this is the equivalent value of pixel 2 on the range of 0 to 255

But...the limit is restricted to Pixel1 which on this case is limited to 10 so...
NewPixel2 = 176.666805/25.5 = 6.92811


So...when Pixel1 =10, the value of pixel2 must be 6.92811

On this case it fits the assumption of pixel1 > pixel2



Is this logic correct ?

Note: Now that i found... The resultant value is the same as (10-30.7189%), but...is it correct ?
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

avcaballero

I'd like to help but I must confess that I'm a bit loss in the argumentation. If you want to start from a point x to a point y in n steps, you could calculate the lengths of these steps by (y-x)/n. If the last step overcome the last point you'll have to truncate it, since I guess that the steps value are float values and the starting and end points are integers.

guga

Hi Caballero...Thanks....I´ll try to explain more clear. I´l building an algorithm for super resolution. In one of the functions it calculates the resultant sum of the neighbor pixels by a multiplication matrixes from a vertex (Matrixes 4x4, 6x6 and 9x9 and vertices values of the same length: 4, 6, 9).

The general rule for the matrix multiplication is row wise. The math operation works on 2 stages, like this, for example:

1st Stage:

Input this: [Vertex: F$ 30, 200, 50, 100] ; <--- The values of each pixel (related to one of the channels only), retrieved from a specific position on the image. For example...say these values came from the pixels in the Green Channel.

Multiplied by the correspondent matrix (This is not the values i used...I putted this values here mainly as example of how it works). Btw: The matrix CAN contain negative values as well:

       [Matrix4x4: F$   1,      0,     0,     0
                             -1.0, 1.0,     0,     0
                             -1.0,    0,   1.0,    0
                              1.0, -1.0, -1.0, 1.0]

Resulting in something like:
        Vertex*Matrix4x4 =
                            30*1+200*0+50*0+100*0 = 30 ; Label it as VertexResult.Data1 for example
                            30*-1+200*1+50*0+100*0 = 170 ; Label it as VertexResult.Data2 for example
                            30*-1+200*0+50*1+100*0 = 20 ; Label it as VertexResult.Data3 for example
                            30*1+200*(-1)+50*-1+100*1 = -120 ; Label it as VertexResult.Data4 for example


So, the resultant value is a array of 4 Floating Points (on this case, but it can be integer etc...I´ll use it here as Float since this is the way i tests it preliminary). So, let´s label the results as:

[VertexResult:
VertexResult.Data1: F$ 30
VertexResult.Data2: F$ 170
VertexResult.Data3: F$ 20
VertexResult.Data4: F$ -120]


Note: VertexResult.Data1 (Whose value now is 10 rather then the original 30) is always the reference pixel. I mean, it is the pixel located at a certain coordinate from where we will start the analysis to compute their neighbor values and see how much each  pixel influences on each other

On the 1st stage i can however, also uses other matrices multiplications with different sizes then a 4x4 matrix multiplied by 4 pixels. Other stages uses a multiplication of 6 pixels by a 6x6 matrix and 9 pixels by a 9x9 matrix. But.....i´ll avoid posting it here to make more clear for you to follow, ok ?

So, i have now 4 Floating Points values that will be passed onto the 2nd stage as follows. Note: The 2nd stage will always produce 4 Floats (Or Dwords, depending of what is being chosen) regardless the original amount of inputted values of the vertexes multiplication. So, the resultant array of values from vertex x Matrix will always produce on this stage a array of 4 Floats/dwords:

2nd Stage

VertexResult.Data1, VertexResult.Data2 ... are used to retrieve the final value which i´ll store in the labels TmpVertex.Data1, TmpVertex.Data2...., ok ?

TmpVertex.Data1 = VertexResult.Data1+(1/2)
TmpVertex.Data2 = VertexResult.Data1+(1/2) + VertexResult.Data2*(3/10)
TmpVertex.Data3 = VertexResult.Data1+(1/2) + VertexResult.Data3*(3/10)
TmpVertex.Data4 = VertexResult.Data1+(1/2) + VertexResult.Data2*(3/10) + VertexResult.Data4*(9/100)


Now...regarding truncating....The problem relies on the resultant values of TmpVertex.Data1, TmpVertex.Data2, TmpVertex.Data3 and TmpVertex.Data4. If any of them are outside the range (0 to 255) they will be truncated as follow:

    mov eax D$TmpVertex.Data1
    If eax <s 0
        xor eax eax
    Else_If eax >s 255
        mov eax 255
    End_If
    mov D$TmpVertex.Data1 eax


So....for those 2 stages we have the following properties for the resultant values in TmpVertex.DataXXX

  • a) The values are always positive (Float or integer or whatever you use)
  • b) The values are always in the range of 0 to 255 (I using here the non-normalized values to make it easier to understand what i´m doing, ok ?)

Note: The resultant values in the Array TmpVertex.DataXX will later be used as a measure of distance to compute the final value of the new pixel that will be created at a specific position, but i´ll omit it here for easier comprehension since these are the steps and method i want to change before the algorithm continues, ok ?

But...regardless these results, this method is not desirable. Let´s say i don´t want them to be truncated and find a way where all of the values (in TmpVertex.DataXXXX) are always positive inside on the range of 1 to 255. Thinking on that , i started on the desirable result of the new pixels that must fits to these new set of properties:

  • a) The values are always positive (Float or integer or whatever you use)
  • b) The values are always in the range of 1 to 255 (I using here the non-normalized values to make it easier to understand what i´m doing, ok ?) Why min = 1 ? It´s due to the min values on spherical color space as explained below
  • c) All the values are correspondent to each accordingly  to the results of the vertex x matrix multiplication .

But...how to achieve that ? I´ll assume the premises that each pixels influences the next one somehow, like on the same way a photon of light influences the other nearby, resulting on a light of a given wavelength, for example. So the "light" (value of each pixel) must interferes on the neighbor pixels somehow.

Thinking on that, i realized that the values of TmpVertex.DataXX on this stage (and others that uses matrices different then 4x4, such as 6x6 and 9x9) uses powers of (3/10) to generate the resultant values. Like this:
TmpVertex.Data4 = VertexResult.Data1+(1/2) + VertexResult.Data2*(3/10) + VertexResult.Data4*(9/100) is the same as:
TmpVertex.Data4 = VertexResult.Data1+(1/2) + VertexResult.Data2*(3/10) + VertexResult.Data4*(3/10)^2

And other parts of the algorithm uses always power of (3/10) for compute the resultant values of  TmpVertex.DataXX....so, each expression inside of it is a sum where one of it´s values is always X*(3/10)+Y*(3/10)^2+Z*(3/10)^3 for example.
(Where X = VertexResult.Data2, Y = VertexResult.Data4 etc etc etc)


So....to achieve the new properties wanted i can do the 2nd stage behave as this new set of formulas:



Let´s name this as Equation4x4 since the values were achieved by a vertex*matrix of 4x4

        TmpVertex.Data1 = VertexResult.Data1 ; without adding 1/2 to avoid inaccuracy and negative values results..
        TmpVertex.Data2 = TmpVertex.Data1 + VertexResult.Data2*(3/10) - (3/10) ;  and subtracting from now on (3/10) to avoid this and the next ones exceed 255
       (TmpVertex.Data3)^2 = (TmpVertex.Data2)^2 + (VertexResult.Data3*(3/10))^2 - (3/10)^2
       (TmpVertex.Data4)^3 = (TmpVertex.Data3)^3 + (VertexResult.Data4*(3/10))^3 - (3/10)^3


And here is where starts the logic questioning and how i reached it.  If i use the above formulas it then matches the new needed properties. Also, subtracting 3/10 from VertexResult.Data1 also avoid to use values as 0, since 0 cannot be used for spherical perceptual uniformity color spaces which makes sense, since 0 is the axis of the encounter of the 3 vertices of RGB, so when R and G and B are 0 in the 3D coordinate system, it means that all of them are in the same place at the origin of the axis which is impossible, since 3 pixels cannot occupy the same space (reached at 0). Therefore, our range fits also the properties of spherical colorspaces which is from 1 to 255 (Which will never reach full 255 also, btw)

Doing that way we can prevent the values of VertexResult.Data be negative, since (TmpVertex.Data2)^2 + (VertexResult.Data3*(3/10))^2 -(3/10)^2 cannot be negative. Therefore, the resultant valid value of TmpVertex.Data3 is always a positive value bigger or equal to 1.

But.. we could in theory have negative values for VertexResult.Data4 and resulting in a negative of TmpVertex.Data4, right ? After all, the VertexResult is the value of a  Pixel computed as a multiplication and sum of Pixel Values*MatrixValue, where Matrix Value can have negative as explained in stage1. For example, the matrix to be multiplied can contain values as -0.25, -1, 0, 1, -75 etc etc etc etc. So it can be positive or negative. So, TmpVertex.Data4 may result in negative values, right ?

Well....not really. If we expand the array of TmpVertex.DataXXX, then the next power would be a 4, which also cannot have negative values (The result values of power of 4 cannot have negative result on the same way a square root cannot produce negative values) . Since, on this situation TmpVertex.Data5 should be represented as:
    (TmpVertex.Data5)^4 = (TmpVertex.Data4)^4 + (VertexResult.Data5*(3/10))^4  - (3/10)^4

It would also implies that TmpVertex.Data4 is a positive value (as well as VertexResult.Data5).

But the equation does not have TmpVertex.Data5. Well. it don´t...but each TmpVertex.DataXX represents the resultant value of a pixel on a image, right ? And a image is not formed only by 4 pixels. In fact, since we assume each pixel (Light) influences the other, we also have TmpVertex.Data5, TmpVertex.Data6, TmpVertex.Data7....TmpVertex.DataN. But those values are calculated according to a given position of the image whose formula uses only the 4 pixels near each other to recalculate their values and see how much they are influenced by each other.

So, for these equations we can safely assume that both expressions (TmpVertex.DataXXX and VertexResult.DataYYY) must be positive. And also we can have new properties and only 1 restriction:

Restriction


  • a) VertexResult.Data1 (Therefore TmpVertex.Data1) is used as a reference to compute all of this, so it´s value cannot be changed by the forwarding calculations.
    So, whatever we do to compute the amount of influence of the remaining pixels values, the value at TmpVertex.Data1 must remain unchanged on this step of the analysis.

Properties


  • a) Both expressions and formulas result in positive values. Ie.: TmpVertex.Data2, TmpVertex.Data1 etc...and the inner contents (Expressions) of it: TmpVertex.Data1 + VertexResult.Data2*(3/10) - 3/10. Expression1 = TmpVertex.Data1, Expression2 = VertexResult.Data2*(3/10)
  • b) The value of VertexResult.Data1 will always influence on the resultant values of the other array of TmpVertex.DataXX
  • c) The value of the next array TmpVertex.DataXXX will always be bigger then the previous one. (Since they are a sum of the previous one plus VertexResult.DataXXX)
  • d) According to the item "c" above we know that, for example their values most likely must be different from each other or must have big differences (distances) from each other. Otherwise, at least one of the resultants values of the TmpVertex.DataXXX are the same as other one (If not all of them are the same). For example, if we have VertexResult.Data1 = 1, VertexResult.Data2 = 1, VertexResult.Data3 = 1, VertexResult.Data4 = 1, it will result on TmpVertex.DataXXX on the same value which is impossible, such as: TmpVertex.Data1 = 1, TmpVertex.Data2 = 1, TmpVertex.Data3 = 1, TmpVertex.Data4 = 1. On this case it is impossible because they are the same and also smaller then 1. Or....if we input the values for VertexResult.DataXX as (2, 1, 2, 1), it will produce these values for  TmpVertex.DataXX (2, 2, 2.066 2.066) which also is impossible because the values of TmpVertex.Data are different from each other one bigger then the previous one
  • e) Considering that each TmpVertex.DataXX is bigger then it´s previous one and considering that TmpVertex.Data1 = VertexResult.Data1, the value of it´s pixel can never be 255, otherwise the value of TmpVertex.Data2 shoule be 256

    All of these leads to interesting properties that can be applied to build other kind of filters as long we understand how each one of the equations in TmpVertex.Data1, TmpVertex.Data2...are related to each other.

    We can start like this:

    For equation4x4 (in TmpVertex.Data2) we know that the 1st expression (TmpVertex.Data1) may always bigger then the 2nd one (VertexResult.Data2*(3/10) -3/10), therefore we can find the limits:

        From TmpVertex.Data2 we know that TmpVertex.Data1 > VertexResult.Data2*(3/10) - (3/10). Since all pixels have a maximum value of 255 we know from the 2nd expression
        that the maximum value for VertexResult.Data2 = 255*3/10 -3/10 = 76.2
        So, instead searching for the maximum value of 255 for Vertex2 we could truncate the value as (Even considering that truncating is not desirable anyway):
       
        mov eax D$TmpVertex.Data2
        If eax <s 0
            xor eax eax
        Else_If eax >s 76.2
            mov eax 76.2
        End_If
        mov D$TmpVertex.Data2 eax     

        This will fit both expression, as long Pixel 1 is bigger then Pixel 2. Their ranges are:
        Pixel1 = 0 to 255
        Pixel2 = 0 to 76.2

    But...i´m not sure if the last assumption is correct (I mean, TmpVertex.Data1 must always be bigger then VertexResult.Data2*(3/10) -3/10) . It does not seem so. It looks like it can be found some interesting properties on each of the equations, but i´m confused how to reach them.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com