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