기본 콘텐츠로 건너뛰기

추천 가젯

[프로그래밍 이야기 6] 포터블 라이터기의 재발견: 웹소켓과 스크립트가 만든 현장 대응 파이프라인

 임베디드 장비나 FPGA 칩이 탑재된 하드웨어를 현장에서 다룰 때, 가장 고민스러운 부분은 펌웨어 라이팅 환경을 구축하는 일입니다. 공장 PC나 현장 컴퓨터에 무겁고 거대한 벤더 전용 프로그램(IDE)을 일일이 설치하고 환경을 설정하는 것은 지극히 비효율적입니다. 이때 가장 똑똑하고 유연한 접근법은 공장 PC에 무언가를 설치하려 애쓰는 대신, 엔지니어의 노트북 한 대를 즉시 '포터블(Portable) 라이터기'로 탈바꿈시켜 현장에 투입하는 것입니다. 노트북을 포터블 라이터기로 만드는 전략과 웹소켓 노트북을 이동식 포터블 라이터기로 활용하기 위해 거창한 프로그램을 깔 필요는 전혀 없습니다. 핵심은 펌웨어를 입히는 CLI(명령줄 인터페이스) 툴과, 이를 원격에서 실행해 줄 지극히 단순하고 가벼운 웹소켓(WebSocket) 서버 하나만 준비하는 것입니다. 중요한 점은 여기서 사용하는 웹소켓 프로그램이라는 것이 결코 복잡하거나 무거운 시스템이 아니라는 사실입니다. 단 몇 킬로바이트 수준의 경량 훅(Hook) 역할만 수행하는 웹소켓 서버를 노트북에 띄워두면, 공장 PC 환경을 오염시키지 않고도 노트북 한 대가 완벽한 이동식 라이팅 단말기로 변신합니다. 가장 가벼운 웹소켓 훅과 Shell 스크립트의 결합 이 시스템의 실체는 놀라울 정도로 가볍고 명확합니다. 노트북 내부에서는 하드웨어(.sof)를 구운 뒤 MCU 펌웨어(.elf)를 연달아 다운로드하는 아래의 Shell 스크립트가 실행의 중심을 잡습니다. // flasher.sh - FPGA 및 Nios II 펌웨어 연속 라이팅 스크립트 #!/bin/bash 1. FPGA Hardware (.sof) 구우기 #!/bin/bash echo "Hello World" echo "=== Programming FPGA Hardware ===" quartus_pgm -c "USB-Blaster [1-4]" -m JTAG -o "p;mcu.sof...

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에 대해 불투명한 레이어 쪽이 더 부각되도록 되어 있다. 

    교환 법칙이 성립한다.





    댓글