이 블로그 검색

2020년 10월 19일 월요일

frei0r - 오픈소스 이미지 콤포지션(트랜지션) 상세설명.(1) - Mixer2 Part1 alpha...

    Frei0r

    Frei0r은 Natron이나 kdenlive같은 비디오 에디터에서 사용되는 composition,transition, merge 툴이다. 

    adobe의 트랙 매트 (track matte)효과를 kdenlive에서 어떻게 구현할지를 생각하다가 이것으로 구현할 수 있을 것 같아 찾다가, 너무 이름이 직관적이지 않아 쓸 때마다 헛갈릴 것 같아 정리를 해놓는다. 



    Mixer2 

    Mixer2는 8비트 unsigned int형의 자료를 사용하여 각 픽셀의 색상정보를 저장한다. Mixer3을 봐야 알겠지만, 더 큰 자료형을 사용하는 부분이 구현이 되어있지 않다면, frei0r은 사용하지 않는 것이 좋을 것이다.  

    코드 호출이 어떻게 되는지를 몰라서, 일단은 A를 윗 레이어, B를 아래 레이어로 생각하고 글을 쓴다.    kdenlive에 넣어서 테스트 해보니, A가 아래 B가 위로였다. natron에서는 다를 수 있으므로 1번 2번으로 전부 다시 고쳤다. 

     
    •  ᅟAddition (더하기)
    더하기 효과는 간단하다. 윗 이미지와 아래 이미지의 rgb값을 더 한다. 최대 값은 255로 한다. 

    알파의 값은 두 알파의 최소 값으로 한다. 

    고로 항등 image에 해당하는 윗 이미지는 (0,0,0,255)로 이루어진 이미지이다. 

    2번 레이어의 알파는 min연산이다보니, 중간 값을 이용하기 보다는, 이진의 마스크 효과를 사용할 수 있고, 윗 레이어를 통해 닷지 효과처럼 사용한다.  

    그리고 중요한 점 중 하나는, 윗레이어(마스크)와 아래레이어(배경)의 교환 법칙이 성립한다는 것이다. 많은 효과들이 교환 법칙이 성립하지만, 아닌 것들도 많다. gimp의 이미지 합성 툴 가운데에도 그런 것이 있다. 

    그룹레이어를 사용하지 못하는 경우에 교환 법칙이 성립하는 것을 유용하게 사용할 수 있고, (서로는 순서가 상관 없지만 그 각각도 위아래가 따로 있으므로 )노드 방식의 이미지 에디터에서 연결순서가 바뀌어도 같은 경과가 나오기에 유용하다. 이제 아래부터는 그냥 교환법칙이 성립한다로 끝내도록 한다. 


    • Addition_alpha (알파더하기)
    Addition_alpha는 대표적인 잘못이름지어진 콤포지션 효과이다. 
    이름만 들으면, 마스크의 알파 값이 더해질 것 같은 이름이지만 전혀 다른 효과를 가진다. 

    1번의 rgb에다가  pre-multiplied RGB(이하 pRGB) 값을 더하는 효과이며,
    결과값은 완전 불투명이다. 

    마치 이미지 에디터에서의 더하기라고 생각하면 된다. 레이어를 투명하게도 하지만, 브러쉬 툴의 알파를 이용해서 여러번 덧칠한다거나 하는 느낌을 주지 않을까??

    • Alphaatop( alpha atop)

    매우 복잡하다. 

    일단, 결과값의 알파는 2번의 알파와 같다. 

    결과의 알파가 0이라면, 리소스 낭비를 줄이기 위해 모든 결과값을 0으로 한다. 이후에도 알파값을 먼저 계산하면 다 그러해서 설명하지 않는다. 

    0이 아닐 때는,  다음과 같은 계산을 거친다. 

    w1 = alpha2

    w2 = 255 - alpha1

    rgb_dst = [(prgb1 * w1 ) + (prgb2*w2)]/ alpha_dst

    rgb_dst = rgb1*alpha1 + rgb2* [(1-alpha1)]

    직관적으로 이해하기 어렵다. 

    2번의 알파값이 그대로 작동하므로 알파마스크처럼 사용되며, 

    1번의 알파값에 따라, 1,2번의 색상의 rgb 사잇값을 사용한다. 

    • alphain 

    결과값의 알파는 1,2번 알파의 곱이다.  

    결과값의 RGB는 1번의 RGB값을 결과값의 RGB값으로 하도록 되어 있다. 

    rgb_dst = (rgb1*alpha1/255) * alpha2 / alpha_dst
    그렇다면 prgb_dst = rgb1*alpha1*alpha2가 될 것이다. 
    막상 약분이 된다고 하면, 
    rgb_dst = rgb1이다. 약간의 차이는 uint8 연산이다보니 여기저기서 계단 현상이 일어난다. 이것이 중요한 부분일지는 모르겠다. 

    어쨌든 대충 alpha_dst= alpha1*alpha2 
                      rgb_dst ≃ rgb1

    최신 깔끔한 구현에는 그냥 두번째 알파채널 또는, 레이어마스크 처럼 작동하지 않을까?

    단순한 알파마스크로 색상은 아무변화를 주지 못하며, 흰색일수록 불투명하다. 

    • alphainjection (오래된 api라 1,2번이 다를 수 있음)
    1번의 rgb값의 평균값을 결과값의 알파값으로, 2번의 rgb를 그대로 사용한다. 

    fill/key로 분리해서 전송하는것과 같다고 보면 된다. 

    물론 rgb의 평균값이 yuv채널의 y값과 다르기 때문에 생각한 것과는 다를 수 있다. 

    matte의 경우에는 루마 값을 알파값으로 사용한다. (kdenlive) 
    (matte는 frei0r이 아니다.  mlt framework sse!! code)

    alphainjection이 kdenlive에서는 없는 것처럼 보인다. 


    • alphaout
    alphaout은 alphain과 거의 같으나, 알파 대신 (255-alpha) 값을 사용한다. 반대로 작동한다. 시작효과를 끝에다가 붙인다면, 시작과 끝이 맞아서 아름답지 않을까?

    • alphaover
    무언가 수식만 봐도 미친 것 처럼 보인다. 편의상 0-1의 실수형 색상이라고 할 때, 결과값 알파는 다음과 같다. 

    alpha_dst = alpha1*alpha1 + alpha2*alpha2*(1-alpha1)
    alpha1과 alpha2의 제곱사이의 사잇값이다. 1번이 불투명할 때는, 약간의 변화를 2번의 알파가 주며, 알파2의 제곱이 알파1보다 작을 때는 오히려 더 투명하게 된다. 

    결과값 RGB는 다음과 같다.   

    rgb_dst= (rgb1 * alpha1 + pRGB2*(1-alpha1) )/ alpha_dst

    이건 써봐야 알 것 같기는 한데,  같은 수식을 그대로 적용한다. 

    1번에 있는 투명한 부분이 매우 밝게 강조 된다. 나누기 연산이 있으면 일단, 뭔가 특별한 상황에서만 써야지 결과값이 맛이 많이 간다. 



    • alphaxor
    alpha간 xor연산을 할 것 같지만 아니다. 또는 구현을 내가 몰라서일 수도 있다. (뭐 근데 xor연산을 다른 방법으로 하는건 좀 이상하다. 미치지 않고서는)

    결과값 alpha = alpha1*(1-alpha2)+ alpha2*(1-alpha1)
    모두 투명하거나 불투명하다면, 불투명하게, 
    하나만 투명할 때 투명하게 결과가 나온다. 

    비트 단위의 xor이 아닌 불투명도라는 정도에 대한 xor이다. 

    색상은 다음과 같다. 

    rgb_dst= (pRGB1 * (1-alpha2) + pRGB2* (1-alpha1) )/ alpha_dst

    pRGB에 대해 불투명한 레이어 쪽이 더 부각되도록 되어 있다. 

    교환 법칙이 성립한다.





    댓글 없음:

    댓글 쓰기

    가장 많이 본 글