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.

 Doom9's Forum histogram matching/curve computing question
 Register FAQ Calendar Search Today's Posts Mark Forums Read

 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
 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.
 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!)
6th March 2010, 14:44   #4  |  Link
zee944
Registered User

Join Date: Apr 2007
Posts: 240
Quote:
 Originally Posted by Didée 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.
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.

 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.
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 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!)

7th March 2010, 09:41   #7  |  Link
zee944
Registered User

Join Date: Apr 2007
Posts: 240
Quote:
 Originally Posted by Didée 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 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?)

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 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.

 7th March 2010, 21:59 #9  |  Link LaTo LaTo INV.     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! __________________ AutoAdjust SmoothAdjust MCTemporalDenoise LSFmod GradFun2DBmod Last edited by LaTo; 8th March 2010 at 19:34.
8th March 2010, 21:22   #10  |  Link
zee944
Registered User

Join Date: Apr 2007
Posts: 240
Quote:
 Originally Posted by LaTo 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.

9th March 2010, 07:43   #11  |  Link
LaTo
LaTo INV.

Join Date: Jun 2007
Location: France
Posts: 701
Quote:
 Originally Posted by zee944 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 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.

Last edited by LaTo; 9th March 2010 at 19:57.

 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.
 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
13th March 2010, 12:10   #14  |  Link
zee944
Registered User

Join Date: Apr 2007
Posts: 240
Quote:
 Originally Posted by LaTo 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 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?

13th March 2010, 17:53   #15  |  Link
LaTo
LaTo INV.

Join Date: Jun 2007
Location: France
Posts: 701
Quote:
 Originally Posted by zee944 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
MatchHistogram(src,clip,debug=true)```
And maybe it will output the correct curve (it depends on how HistogramAdjust works...)

 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
14th March 2010, 04:33   #17  |  Link
zee944
Registered User

Join Date: Apr 2007
Posts: 240
Quote:
 Originally Posted by LaTo 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 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.

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 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`

I was looking forward to working with this. Are any updated or fixed versions available?

 7th July 2015, 16:57 #19  |  Link StainlessS HeartlessS Usurer     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.
 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.