Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 5th March 2010, 23:52   #1  |  Link
zee944
Registered User
 
Join Date: Apr 2007
Posts: 240
histogram matching/curve computing question



Dear Everyone,

I have a problem with histogram matching.
I have the original picture on the left (above). I want to make it look like the picture on the right through applying a luma curve to it. How can I figure out the curve I need by comparing the histograms? As you can see, in the above example the desired curve is known, but obviously normally I only have the pictures.

I've written a little program which creates the histograms. I thought it'll be very simple to calculate out the needed luma curve, but I've just realized it's not. I tried comparing "column" to "column" but I ended up with very irrealistic curves. They didn't look like the above. There must be a working mathematical way to work it out. Any ideas?


Full size pictures:
http://i179.photobucket.com/albums/w...eredetikep.jpg
http://i179.photobucket.com/albums/w..._elkurtkep.jpg
zee944 is offline   Reply With Quote
Old 6th March 2010, 04:14   #2  |  Link
Dogway
Registered User
 
Join Date: Nov 2009
Posts: 1,041
Do you mean you want to reverse what is shown in the picture?

Curves work like an histogram but in a diagonal axis. Just a question, do you know any curves filter for avisynth? im very interested.

In this particular case the best you can do is by eye. As you have de curve, you can try to do just de opposite. Reference on the grid and reverse the points. Much better, reference the curve graph, and copy the points position, then reverse the value numbers based on the diagonal axis.
Dogway is offline   Reply With Quote
Old 6th March 2010, 14:14   #3  |  Link
Didée
Registered User
 
Join Date: Apr 2002
Location: Germany
Posts: 5,394
You can't reverse such an operation in the general case. Reversal is only possible when the adjusted curve is continuously rising (or continuously falling). If the adjusted curve doesn't meet this criterium, e.g. if there is a sinus-style rise-fall-rise part in the curve, like in the given example, then the projection is not anymore bijective, and cannot be reversed. (Independent input values become the same output value. If you have only the output value, there is no way to transform that value back into some, some other, or yet another value.)

That's basic maths, you can't square a circle.
__________________
- We´re at the beginning of the end of mankind´s childhood -

My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!)
Didée is offline   Reply With Quote
Old 6th March 2010, 14:44   #4  |  Link
zee944
Registered User
 
Join Date: Apr 2007
Posts: 240
Quote:
Originally Posted by Didée View Post
You can't reverse such an operation in the general case. Reversal is only possible when the adjusted curve is continuously rising (or continuously falling). If the adjusted curve doesn't meet this criterium, e.g. if there is a sinus-style rise-fall-rise part in the curve, like in the given example, then the projection is not anymore bijective, and cannot be reversed. (Independent input values become the same output value. If you have only the output value, there is no way to transform that value back into some, some other, or yet another value.)

That's basic maths, you can't square a circle.
Perhaps my post was misleading.
I don't want to actually reverse anything. I don't want to tweak the right picture back to the left.

Normally I only have the two images, the left and the right and no curve at all. The curve is what I want to find out: a curve which makes the left image look (nearly) like the right one.

In the example above, the desired curve is already there but that's because it's just an artificial example I created for further examination. So what I need is to calculate out the curve you see in the middle on the pic by comparing the two images.

Is this impossible too?

Last edited by zee944; 7th March 2010 at 11:19.
zee944 is offline   Reply With Quote
Old 6th March 2010, 14:55   #5  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,406
If you have both images, then for each input luma value (at least for those values present in the input), you can see what output value it maps to, giving you your curve.
Gavino is offline   Reply With Quote
Old 6th March 2010, 15:04   #6  |  Link
Didée
Registered User
 
Join Date: Apr 2002
Location: Germany
Posts: 5,394
Quote:
Originally Posted by zee944 View Post
Perhaps my post was misleading.
I don't want to actually reverse anything. I don't want to tweak the right picture back to the first.
...
Is this impossible too?
It depends on the actual difference. See: you have two such pictures, and want to make one look like the other. Now, if the theoretical curve to make the other look like the one (i.e. the reverse direction of what you want to do) would imply such a not-bijective projection, then it is imposible.


Apart from that, there is a "match histogram" filter for Avisynth. I never tried it (don't even have it). Training for your search skills!
__________________
- We´re at the beginning of the end of mankind´s childhood -

My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!)
Didée is offline   Reply With Quote
Old 7th March 2010, 09:41   #7  |  Link
zee944
Registered User
 
Join Date: Apr 2007
Posts: 240
Quote:
Originally Posted by Didée View Post
It depends on the actual difference. See: you have two such pictures, and want to make one look like the other. Now, if the theoretical curve to make the other look like the one (i.e. the reverse direction of what you want to do) would imply such a not-bijective projection, then it is imposible.

Apart from that, there is a "match histogram" filter for Avisynth. I never tried it (don't even have it). Training for your search skills!
Oh, I see now. You're saying if the difference between the two histograms is consistent (basically: their shape look similar) then it is possible. Otherwise not.

I couldn't find histogram matching filter. If you're thinking of ColourLike, that's not a very useful filter and doesn't give me a luma curve anyway.

Quote:
Originally Posted by Gavino View Post
If you have both images, then for each input luma value (at least for those values present in the input), you can see what output value it maps to, giving you your curve.
That's what I thought... but it didn't work for me. My logic was that if, say, the value of luma 127 is '50' units in one histogram, and '56' in the other histogram, then I should add 56/50 = 1.12 gain in the curve at the same point. So 127*1.12 = '142' at luma 127. But I ended up with an exaggarated, unreal curve.

Before I did that I realized that this step won't make the 50 units the desired 56. It'll make all the luma 127 pixels 142. But I thought these steps will compensate each other and the result will be fine. Now that I've written it down I can see even more clearly why this is not working. The right logic must be more complex. Any ideas?

(Perhaps I have to find out the average luma and act the opposite way below and above that gradually?)
zee944 is offline   Reply With Quote
Old 7th March 2010, 14:04   #8  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,406
Quote:
Originally Posted by zee944 View Post
That's what I thought... but it didn't work for me. My logic was that if, say, the value of luma 127 is '50' units in one histogram, and '56' in the other histogram, then I should add 56/50 = 1.12 gain in the curve at the same point. So 127*1.12 = '142' at luma 127. But I ended up with an exaggarated, unreal curve.
What I meant was to look at the individual pixels, not the histograms. For each pixel, examine input luma and output luma, and construct a table which gives you a mapping from input values to output values. This assumes that a given input luma value always produces the same (or very close to the same) output value, regardless of position - if you find this is not the case, then no possible 'curve' can be found that corresponds to the transformation.

If you want to work solely from the histograms, then it can be done if (as Didée hinted) you assume a monotonic curve. Then you can pair off values from the two histograms in ascending or descending order of luma.
Gavino is offline   Reply With Quote
Old 7th March 2010, 21:59   #9  |  Link
LaTo
LaTo INV.
 
LaTo's Avatar
 
Join Date: Jun 2007
Location: France
Posts: 701
Just a quick try, without testing (only on your sample).

Code:
MatchHistogram(img1,img2,debug=false)
img1 is the original image (the left one in your example).
img2 is the target image (the right one in your example).
The output is img1 with the calculated curve.

Use debug=true if you want to see the calculated curve.

Here is the plugin: MatchHistogram.dll

It doesn't work anytime (cf. Didée), for example inverse img1 & img2 and... oups!

Last edited by LaTo; 8th March 2010 at 19:34.
LaTo is offline   Reply With Quote
Old 8th March 2010, 21:22   #10  |  Link
zee944
Registered User
 
Join Date: Apr 2007
Posts: 240
Quote:
Originally Posted by LaTo View Post
Just a quick try, without testing (only on your sample).
LaTo, judging from the images this is genius. Does it work only by using the histograms? No pixel-pixel comparing at all?

Isn't the plugin broken? It's 15,360 bytes and AviSynth [2.5.8] tells me "unable to load MatchHistogram.dll". I couldn't find out why yet.
zee944 is offline   Reply With Quote
Old 9th March 2010, 07:43   #11  |  Link
LaTo
LaTo INV.
 
LaTo's Avatar
 
Join Date: Jun 2007
Location: France
Posts: 701
Quote:
Originally Posted by zee944 View Post
LaTo, judging from the images this is genius. Does it work only by using the histograms? No pixel-pixel comparing at all?
Really it isn't genius, here is the code:
Code:
int temp[2][256] = {{0}};
unsigned char curve[256] = {0};

for (int h = 0 ; h < height ; h++) {
	for (int w = 0 ; w < width ; w++) {
		temp[0][src1[(h*pitch)+w]] += src2[(h*pitch)+w];
		temp[1][src1[(h*pitch)+w]] += 1;
	}
}

for(int i = 0 ; i < 256 ; i++) {
	if( temp[1][i] != 0 )
		curve[i] = temp[0][i] / temp[1][i];
	else
		curve[i] = i;
}
Now you have your curve, curve[input] = output.

Quote:
Originally Posted by zee944 View Post
Isn't the plugin broken? It's 15,360 bytes and AviSynth [2.5.8] tells me "unable to load MatchHistogram.dll". I couldn't find out why yet.
It works on my PC... Try to re-download it!

Last edited by LaTo; 9th March 2010 at 19:57.
LaTo is offline   Reply With Quote
Old 9th March 2010, 22:00   #12  |  Link
AVIL
Registered User
 
Join Date: Nov 2004
Location: Spain
Posts: 401
Hi,

It also works in my PC (loaded explicitilly) and works OK. ¿BTW a YUY2 version could be possible?. Anyway thanks for the new plugin.
AVIL is offline   Reply With Quote
Old 10th March 2010, 04:13   #13  |  Link
vcmohan
Registered User
 
Join Date: Jul 2003
Location: India
Posts: 781
I could not follow completely the discussion. Histogram matching can not exactly match, it only tries to produce a best approximation as it can not fill holes. My HistogramAdjust plug in. Can be tried.
__________________
mohan
my plugins are now hosted here
vcmohan is offline   Reply With Quote
Old 13th March 2010, 12:10   #14  |  Link
zee944
Registered User
 
Join Date: Apr 2007
Posts: 240
Quote:
Originally Posted by LaTo View Post
Really it isn't genius, here is the code:
It's simple indeed. Pixel to pixel. Using the histograms would be genius... and probably impossible to achieve a curve that good.

My problem with pixel-with-pixel comparing you and Gavino suggested that the image geometry has to be exactly the same. But I often want to capture the luma levels of an image and apply that to another image with different content. Imagine a frame of a video which shows a house. And another frame from another video footage (recorded by a different cam) which shows the same house from another angle. Pretty similar in subject, but quite different in geometry. I have to match the luma levels, but pixel-to-pixel mapping doesn't work at all. That's why I want to work from histograms.

Quote:
Originally Posted by vcmohan View Post
I could not follow completely the discussion. Histogram matching can not exactly match, it only tries to produce a best approximation as it can not fill holes. My HistogramAdjust plug in. Can be tried.
Your plugin is interesting. I've met with it years ago already. But it doesn't show the curve it applies on the target video. Could you perhaps modify it to create a curve?
zee944 is offline   Reply With Quote
Old 13th March 2010, 17:53   #15  |  Link
LaTo
LaTo INV.
 
LaTo's Avatar
 
Join Date: Jun 2007
Location: France
Posts: 701
Quote:
Originally Posted by zee944 View Post
Your plugin is interesting. I've met with it years ago already. But it doesn't show the curve it applies on the target video. Could you perhaps modify it to create a curve?
Try:

Code:
src=last
clip=src.HistogramAdjust(xxx)
MatchHistogram(src,clip,debug=true)
And maybe it will output the correct curve (it depends on how HistogramAdjust works...)
LaTo is offline   Reply With Quote
Old 14th March 2010, 04:06   #16  |  Link
vcmohan
Registered User
 
Join Date: Jul 2003
Location: India
Posts: 781
HistogramAdjust uses the Histogram curve of the video used for matching. So the curve is that of the clip used for matching. It can be a single frame or frame by frame as opted.
__________________
mohan
my plugins are now hosted here
vcmohan is offline   Reply With Quote
Old 14th March 2010, 04:33   #17  |  Link
zee944
Registered User
 
Join Date: Apr 2007
Posts: 240
Quote:
Originally Posted by LaTo View Post
And maybe it will output the correct curve (it depends on how HistogramAdjust works...)
MatchHistogram still doesn't work for me. I've no idea yet, will try to find out why.

Quote:
Originally Posted by vcmohan View Post
HistogramAdjust uses the Histogram curve of the video used for matching. So the curve is that of the clip used for matching. It can be a single frame or frame by frame as opted.
I understand that, it is in the documentation and I've also tried it out. It's not the histograms I'm thinking of. You use some mathematical operation to tweak one histogram to look like the other, and this operation can be described with a curve.
zee944 is offline   Reply With Quote
Old 7th July 2015, 15:54   #18  |  Link
fvisagie
Registered User
 
Join Date: Aug 2008
Location: Isle of Man
Posts: 588
Quote:
Originally Posted by zee944 View Post
Isn't the plugin broken? It's 15,360 bytes and AviSynth [2.5.8] tells me "unable to load MatchHistogram.dll". I couldn't find out why yet.
Here I have it as 13,253 bytes, and trying to load it into Avisynth 2.6.0 Alpha 4 fails with
Code:
LoadPlugin: unable to load "C:\Users\fvisagie\Documents\Working\Video evaluation\MatchHistogram.dll", error=0xc1
Obviously auto-loading also fails.

I was looking forward to working with this. Are any updated or fixed versions available?
fvisagie is offline   Reply With Quote
Old 7th July 2015, 16:57   #19  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 8,464
Take a look here at post by a well respected member of the forum [error=0xc1]
http://forum.doom9.org/showthread.ph...98#post1696498
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 7th July 2015 at 16:59.
StainlessS is offline   Reply With Quote
Old 7th July 2015, 17:41   #20  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,177
Wanted to try to see if I can get it to load but the link to MatchHistogram.dll is dead.
Reel.Deel is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 19:07.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.