TL; DR : 2 * 1LSB 삼각 -pdf 디더링이 클램핑으로 인해 0과 1에서 에지 케이스에서 끊어집니다. 해결책은 해당 에지 케이스에서 1 비트 균일 디더링으로 뛰어 드는 것입니다.
나는 이것이 원래 생각했던 것보다 조금 더 복잡하다는 것을 알면서 두 번째 대답을 추가하고 있습니다. 이 문제는 "TODO : 클램핑이 필요합니까?" 2012 년에 정규화에서 삼각 디더링으로 전환 한 이후 내 코드에서. 마침내 그것을 보는 것이 좋습니다 :) 게시물 전체에서 사용되는 솔루션 / 이미지의 전체 코드 : https://www.shadertoy.com/view/llXfzS
우선, 2 * 1LSB 삼각-PDF 디더링을 사용하여 신호를 3 비트로 양자화 할 때보고있는 문제는 다음과 같습니다.
-본질적으로 hotmultimedia가 보여준 것.
대비가 증가하면 문제에 설명 된 효과가 분명해집니다. 가장자리의 경우 출력이 평균적으로 흑백으로 표시되지 않습니다 (실제로 0/1 이상으로 확장 됨).
그래프를 보면 좀 더 통찰력을 얻을 수 있습니다.
(회색 선은 0/1로 표시되며 회색으로도 출력하려고하는 신호이며, 노랑 선은 디더링 / 양자화 된 출력의 평균이며, 빨간색은 오류 (신호 평균)입니다.)
흥미롭게도, 한계에서 평균 출력이 0/1이 아니라 선형 일 수도 있습니다 (소음의 삼각형 pdf 때문일 수 있습니다). 하단을 보면 출력이 왜 분기되는지 직관적으로 이해할 수 있습니다. 디더링 된 신호가 음의 값을 포함하기 시작하면 클램핑-온-출력은 출력의 하단 디더링 된 부분의 값 (음의 값)을 변경합니다. 평균값 증가. 그림은 순서대로 나타납니다 (균일 한 대칭 2LSB 디더링, 평균은 여전히 노란색).
이제 1LSB 정규화 디더를 사용하면 가장자리에 전혀 문제가 없지만 삼각형 디더링의 좋은 속성을 잃게됩니다 (예 : 이 프레젠테이션 참조 ).
(실용적이고 경험적인) 해킹 (해킹)은 엣지 케이스에 대해 [-0.5; 0.5 [균일 디더링)으로 되돌아가는 것입니다.
float dithertri = (rnd.x + rnd.y - 1.0); //note: symmetric, triangular dither, [-1;1[
float dithernorm = rnd.x - 0.5; //note: symmetric, uniform dither [-0.5;0.5[
float sizt_lo = clamp( v/(0.5/7.0), 0.0, 1.0 );
float sizt_hi = 1.0 - clamp( (v-6.5/7.0)/(1.0-6.5/7.0), 0.0, 1.0 );
dither = lerp( dithernorm, dithertri, min(sizt_lo, sizt_hi) );
삼각형 디더링을 나머지 범위에 그대로 유지하면서 가장자리를 고정시킵니다.
따라서 귀하의 질문에 대답하지 않으려면 : 더 수학적으로 견고한 해결책이 있는지 모르겠으며 과거의 석사가 무엇을했는지 알고 싶습니다.) 그때까지는 코드가 계속 작동하도록하는이 끔찍한 해킹이 있습니다.
편집
나는 아마도 신호를 압축하는 것에 대한 The Question에서 주어진 해결 방법 제안을 다룰 것입니다. 엣지 케이스에서 평균값이 선형이 아니기 때문에 입력 신호를 압축하는 것만으로는 완벽한 결과를 얻지 못합니다.
참고 문헌