Correcting Images without Histogram Wrapping?

I have a color image that has been split in to the r g b channels. The information is in the r channel. The background is in the g channel. I want to subtract the one from the other. I have this in a function ...

Function CorrectRedwGreen(th, sf)
    variable th, sf

    DFREF rd = root:rawimages
   
    wave/SDFR=rd redch, redch_corrected, grnch
   
    duplicate/FREE grnch grnchth
    MatrixOP/O grnchth = grnch - th
    grnchth = grnchth < 0 ? 0 : grnchth
    MatrixOP/O redch_corrected = redch - sf*grnchth
   
    return 0
end


Basically, I am removing a threshold from the green and then subtracting a fraction of the threshold-corrected green channel from the red. The test to reset the green channel is my way to try to avoid what I call as a "wrapping" problem in the histogram. I want the negative grayscale values to go to zero, not be reset to the other side of the histogram color (grayscale).

Unfortunately, it does not work. I suspect the wrapping is already done at the subtraction.

What is the correct way to handle this?
Hi,

I have encountered that problem also in may forays into image processing.

One suggestion instead of
MatrixOP/O grnchth = grnch - th

you use
grnchth = max((grnch-th),0)

That will prevent then wrapping at the subtraction point, albeit it will probably be a lot slower that using a matrixop.



Andy
I've ended up for now with this ...

Function CorrectBackground(th, sf, how)
    variable th, sf, how

    // globals
   
    DFREF pdf = root:Packages:ColorByHistogram 
    wave/SDFR=pdf srcimg, srcimg0, bckch
   
    make/FREE/N=1 thvw
    MatrixOP/O thvw = th*maxVal(bckch)/100
   
    variable thv = thvw[0]
   
    // remove offset from background first?

    switch(how)
        case 0:
            MatrixOP/O srcimg = srcimg0 -((sf*bckch/100) + thv)
            break
        case 1:
            Duplicate/FREE bckch bckchF
            MatrixOP/O bckchF = bckch - thv
            bckchF = bckchF < 0 ? 0 : bckchF
            MatrixOP/O srcimg = srcimg0 - sf*bckchF/100
            break
    endswitch
    srcimg= srcimg < 0 ? 0 : srcimg
    return 0
end


This is not so slow. I imagine that MultiThread may come in handy somewhere. But that is alphabetically after MatrixOP, and my brain can only learn one new command at a time any more. :-)

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
jjweimer wrote:


            bckchF = bckchF < 0 ? 0 : bckchF




If you are already using MatrixOP, what's the point of using such slow expressions?

Try:
MatrixOP/O bckchF=greater(bckchF,0)*bckchF


A.G.
WaveMetrics, Inc.
Igor wrote:
jjweimer wrote:

            bckchF = bckchF < 0 ? 0 : bckchF


If you are already using MatrixOP, what's the point of using such slow expressions?
Try:
MatrixOP/O bckchF=greater(bckchF,0)*bckchF



Well, that is another new one for me. Thanks!

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH