View Single Post
Old 2nd December 2012, 15:55   #41  |  Link
zee944
Registered User
 
Join Date: Apr 2007
Posts: 240
Will try that, but meanwhile I have figured out an alternative way I'm rather excited about. Since I wanted a fool-proof method which can be used anywhere and anytime (sometimes I do adding/cropping in RGB32 space too), I thought that I could compare the luma and chroma edges after every "risky" operation, check the possible variations and choose the best match.

This is the raw idea. Using these customized functions for every operation worked alright so far (but I haven't tested fully yet):

Code:
function FixChroma(clip clp)
{
	clp
	GScriptClip("""
		LumaEdges=GreyScale().mt_edge("sobel", U=2, V=2)
		ChromaEdgesN6=MergeChroma(PointResize(width, height, 0,-6)).UToY.PointResize(width, height).mt_edge("sobel", U=2, V=2)
		ChromaEdgesN4=MergeChroma(PointResize(width, height, 0,-4)).UToY.PointResize(width, height).mt_edge("sobel", U=2, V=2)
		ChromaEdgesN2=MergeChroma(PointResize(width, height, 0,-2)).UToY.PointResize(width, height).mt_edge("sobel", U=2, V=2)
		ChromaEdges00=                                             UToY.PointResize(width, height).mt_edge("sobel", U=2, V=2)
		ChromaEdges02=MergeChroma(PointResize(width, height, 0, 2)).UToY.PointResize(width, height).mt_edge("sobel", U=2, V=2)
		ChromaEdges04=MergeChroma(PointResize(width, height, 0, 4)).UToY.PointResize(width, height).mt_edge("sobel", U=2, V=2)
		ChromaEdges06=MergeChroma(PointResize(width, height, 0, 6)).UToY.PointResize(width, height).mt_edge("sobel", U=2, V=2)
		subtitle("no shift")
		AverageLuma(Overlay(LumaEdges, last.UToY.PointResize(last.width, last.height).mt_edge("sobel", U=2, V=2), mode="subtract")) 
\> AverageLuma(Overlay(LumaEdges, ChromaEdges06, mode="subtract")) ? clp.MergeChroma(clp.PointResize(width, height, 0, 6)).subtitle("shift +6") : last
		AverageLuma(Overlay(LumaEdges, last.UToY.PointResize(last.width, last.height).mt_edge("sobel", U=2, V=2), mode="subtract")) 
\> AverageLuma(Overlay(LumaEdges, ChromaEdges04, mode="subtract")) ? clp.MergeChroma(clp.PointResize(width, height, 0, 4)).subtitle("shift +4") : last
		AverageLuma(Overlay(LumaEdges, last.UToY.PointResize(last.width, last.height).mt_edge("sobel", U=2, V=2), mode="subtract")) 
\> AverageLuma(Overlay(LumaEdges, ChromaEdges02, mode="subtract")) ? clp.MergeChroma(clp.PointResize(width, height, 0, 2)).subtitle("shift +2") : last
		AverageLuma(Overlay(LumaEdges, last.UToY.PointResize(last.width, last.height).mt_edge("sobel", U=2, V=2), mode="subtract")) 
\> AverageLuma(Overlay(LumaEdges, ChromaEdges00, mode="subtract")) ? clp.MergeChroma(clp.PointResize(width, height, 0, 0)).subtitle("no shift") : last
		AverageLuma(Overlay(LumaEdges, last.UToY.PointResize(last.width, last.height).mt_edge("sobel", U=2, V=2), mode="subtract")) 
\> AverageLuma(Overlay(LumaEdges, ChromaEdgesN2, mode="subtract")) ? clp.MergeChroma(clp.PointResize(width, height, 0, -2)).subtitle("shift -2") : last
		AverageLuma(Overlay(LumaEdges, last.UToY.PointResize(last.width, last.height).mt_edge("sobel", U=2, V=2), mode="subtract")) 
\> AverageLuma(Overlay(LumaEdges, ChromaEdgesN4, mode="subtract")) ? clp.MergeChroma(clp.PointResize(width, height, 0, -4)).subtitle("shift -4") : last
		AverageLuma(Overlay(LumaEdges, last.UToY.PointResize(last.width, last.height).mt_edge("sobel", U=2, V=2), mode="subtract")) 
\> AverageLuma(Overlay(LumaEdges, ChromaEdgesN6, mode="subtract")) ? clp.MergeChroma(clp.PointResize(width, height, 0, -6)).subtitle("shift -6") : last
	""",  args="clp", local=true)
} 

function smartConvertToRGB32(clip c) {
  c
  ConvertToYV24(chromaresample="point")
  MergeChroma(PointResize(width, height, 0, 1))
  ConvertToRGB32()
}

function smartConvertToYV12(clip c) {
  c
  ConvertToYV12(chromaresample="point")
}

function smartAddBorders(clip clp, int l, int t, int r, int b) {
  clp
  ss=2
  PointResize(width*ss, height*ss)
  AddBorders(l*ss,t*ss,r*ss,b*ss)
  PointResize(width/ss, height/ss)
  IsYUV ? last : clp.AddBorders(l, t, r, b)
}

function smartCrop(clip clp, int l, int t, int r, int b) {
  clp
  ss=2
  PointResize(width*ss, height*ss)
  Crop(l*ss,t*ss,-1*abs(r)*ss,-1*abs(b)*ss)
  PointResize(width/ss, height/ss)
  IsYUV ? last.FixChroma : clp.Crop(l, t,-1*abs(r),-1*abs(b))
}
Still need a few advices:

1. Is "UToY.PointResize()" and "VToY.PointResize()" (later) right? Will the chroma subtituting pixels be at their right place, and not shifted by one or half pixel in any direction?

2. Should I merge the edge mask of U and V (not just U)? Sometimes when the image has dull colors, none of them has enough edges to work with, though.

3. Would it be enough to check only +2 (or zero) shift all the time? Can the correction be different than +2 after numerous conversions and border operations?

4. I happened to notice that my source (DVD 720x480) has a chroma shift to begin with. "MergeChroma(PointResize(width, height, 0, 2))" is too much, "MergeChroma(PointResize(width, height, 0, 1))" would be ideal if there would be such thing as 1 pixel shift in YV12. Is replacing PointResize() with Lanczos4Resize() an accepted solution for that?

Last edited by zee944; 2nd December 2012 at 15:57.
zee944 is offline   Reply With Quote