1 라인의 간단한 이미지 엣지 검출 필터

9359 단어 FPGAPython3Polyphony


이미지 처리. OpenCV가 나돌기 시작했을 무렵에 내용의 소스를 보고 괴로웠지만 그 내부의 복잡성과는 반대로 Python으로부터도 쉽게 사용할 수 있는 것이 받았는지 확실히 그 지위를 쌓았다. 얼마나 간편하게 사용할 수 있을까 하는 것은 퍼지는데 중요한 것일 것이다.

Polyphony에서도 이미지 처리를 원합니다. 한 줄의 간단한 이미지 가장자리를 감지하는 필터를 만듭니다.

여기에서는 9bit의 데이터를 입출력한다. 최상위 비트는 라인의 끝을 가리킨다. 8bit가 실제 픽셀. 3x3 의 필터라면 라인 버퍼를 가져야 하지만 이 간단한 필터는, 전후의 픽셀차로 엣지를 검출한다. 처음에는 1x3로 생각했지만, 이쪽이 좋다고 생각하고 그렇게 바꿨다.

line_edge.py
from polyphony import testbench
from polyphony import rule
from polyphony import module
from polyphony.typing import bit8, bit9
from polyphony.io import Queue
from polyphony import is_worker_running
from polyphony.timing import clksleep


@module
class line_edge:
    def __init__(self, width):
        self.img_in_q  = Queue(bit9, 'in',  maxsize=4)
        self.img_out_q = Queue(bit9, 'out', maxsize=4)
        self.append_worker(self.worker)

    def worker(self):
        with rule(scheduling='pipeline'):
            last_pixel:bit8 = 0
            out_eol_pixel:bit9 = 0
            while is_worker_running():
                eol_pixel:bit9 = self.img_in_q.rd()
                eol:bit9 = eol_pixel & 0x100
                pixel:bit8  = eol_pixel & 0xFF

                out_eol_pixel = eol | (pixel - last_pixel if (pixel > last_pixel) else last_pixel - pixel)

                self.img_out_q.wr(out_eol_pixel)
                last_pixel = 0 if eol else pixel

@testbench
def test(m):
    line_buf = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100 | 0x100]
    for p in line_buf:
        m.img_in_q.wr(p)
        print(m.img_out_q.rd())

m = line_edge(1920)
test(m)

여기서 주목하고 싶은 것이 pipeline 를 지정하고 있는 것. 파이썬의 with를 사용하여 pipeline 화를 (다음 버전의 0.3.3 이후 혹은 현행 devel) 할 수 있다.

with
with rule(scheduling='pipeline'):
            ....
            ....

화상 처리라고 하기 때문에는 제대로 화상 처리하지 않으면 안 된다. Lenna의 이미지를 처리해 봅시다. 테스트 벤치에서 PIL을 사용할 수 없으므로 list를 사용합니다.

testbench
@testbench
def test(m):
    i = 0
    eol = 0
    for p in LENNA:
        if (i % 400) == 399 :
            eol = 0x100
        m.img_in_q.wr(eol | p)
        eol = 0;
        print(m.img_out_q.rd())
        i += 1

m = line_edge(400) # 400x225 (LENNA)
test(m)

좋은 웹페이지 즐겨찾기