2017-03-13 7 views
0

파이썬에서 서브 이미지 검색을하고 있는데 너무 느립니다. 그래서 그것을 Cython으로 변환하는 과정에서 그렇게 간단하지 않다는 것을 알았습니다. 파이썬 측은 바이트를 올바른 것으로 표시하고 (debugPrint를 수행 할 때) 하위 이미지 검색이 테스트되고 완벽하게 작동합니다. 그러나, Cy 변환에 첫 번째 py를 할 때, 나는 걸림돌을 쳤습니다. 파이썬 바이트를 변환하기 위해 내가하고있는 유일한 일은 char * 포인터에 대한 바이트 (...라고 생각한다.)를 할당하는 것이다. 어떻게 든 데이터 덩어리의 소유권을 잃어 가고 있습니까?어떻게 비트 맵을 Cython 함수에 전달합니까? 쓰레기 값을 받고 있어요

cdef struct PixelsBMP: 
    char* data 
    int width, height, bands 


# Here's how I create the bytes: 


cpdef grabPixelsBMP(img=None): 
    if img is None: 
     img = ImageGrab.grab() 
    elif isinstance(img, str): 
     img = Image.open(img) 

    with io.BytesIO() as bytes_io: 
     img.save(bytes_io, 'BMP') 
     data = bytes_io.getvalue() 
     offset = int.from_bytes(data[10:14], byteorder='little', signed=False) 
     data = data[offset:]  # pixels start here 

    cdef PixelsBMP px; 
    px.data = data 
    px.width = img.width 
    px.height = img.height 
    px.bands = 3 if img.mode == 'RGB' else 4 

    return px 


# Here's how I access the bytes: 
cpdef debugPrintPixels(PixelsBMP px): 
    import sys 
    cdef char* d = px.data 
    print('width:', px.width) 
    print('height:', px.height) 
    print('bands (alpha=>4):', px.bands) 

    cdef: 
     int pad_sum = 0 
     int pad = nextMult4Pad(px.width * px.bands) 
     int x, y, offs 

    for y in range(0, px.height): 
     for x in range(0, px.width): 
      offs = px.width * px.bands * y + px.bands * x + pad_sum 
      sys.stdout.write('(' + str(hex(d[offs])) + ',' + str(hex(d[offs + 1])) + ',' + \ 
       str(hex(d[offs + 2])) + ((',' + str(hex(d[offs + 3]))) if px.bands == 4 else '') + ')') 
     print() 
     pad_sum += pad 

가 인쇄 내용 : : 여기

은 관련 코드가 알파 채널 = 255

암 검은 픽셀의 이미지이어야

('width:', 7) 
('height:', 3) 
('bands (alpha=>4):', 4) 
(0x0,0x0,0x0,0x0)(0x0,0x0,0x0,0x0)(0x1,0x0,0x0,0x0)(0x30,-0x3f,0x4a,0x5c)(0x2,0x0,0x0,0x0)(-0x1,-0x1,-0x1,-0x1)(0x0,0x7,0x0,0x0)() 
(0x0,0x0,0x0,0x0)(0x1,0x0,0x0,0x0)(0x30,-0x3f,0x4a,0x5c)(0x2,0x0,0x0,0x0)(-0x1,-0x1,-0x1,-0x1)(0x0,0x4,0x0,0x0)(0x0,0x0,0x0,0x0)() 
(0x1,0x0,0x0,0x0)(0x30,-0x3f,0x4a,0x5c)(0x4,0x0,0x0,0x0)(-0x1,-0x1,-0x1,-0x1)(0x64,0x1,0x0,0x53)(0x0,0x0,0x0,0x0)(0x1,0x0,0x0,0x0)() 

Cython을 사용하여 올바르게 바이트에 액세스합니까?

+0

버퍼링 된 스트림에서 바이트를 가져오고 있기 때문에 Cython 버퍼 문서가 적용되는지 궁금합니다. http://cython.readthedocs.io/en/latest/src/userguide /buffer.html 또는 최신 메모리 뷰, http://cython.readthedocs.io/en/latest/src/userguide/memoryviews.html. – hpaulj

답변

0

이것은 메모리 소유권 문제입니다. bytes_iopx_data이 가리키는 데이터를 소유하고 있습니다. 일부 메모리를 할당하고 데이터를 복사해야합니다.

# at the top of your file 
from libc.stdlib cimport malloc 
from libc.string cimport memcpy 

#replacing px.data = data 
cdef char* data_str = data 
px.data = <char*>malloc(sizeof(char)*len(data)) 
memcpy(px.data,data_str, len(data)) 

구조체가 완성되면 데이터를 해제해야합니다. struct를 Python으로 전달하면 (예 : Python에서 cpdef grabPixelsBMP을 호출하여) 구조체의 사전 복사본을 생성합니다. 사전 복사본이 아닌 구조체가 보유한 데이터를 해제해야합니다. C에서 메모리 관리가 어려울 수 있습니다 ...