简体   繁体   中英

camera image incorrectly formatted in ctypes pointer (python)

I am using a DLL library to call functions to operate a camera in python, and i'm able to retrieve the image using ctypes but it's formatted incorrectly. The returned image is duplicated and half of it is blank. what do i need to do to fix this?

I have a labview program that correctly takes images from the camera, so that is how they are supposed to look like.

Correct image retrieved using Labview

图片来自Labview

Image retrieved using Python: 来自Python的图片

the image is duplicated and also sideways in python.

python code:

from ctypes import *
import numpy as np
import matplotlib.pyplot as plt
mydll = windll.LoadLibrary('StTrgApi.dll')
hCamera = mydll.StTrg_Open()
print(hCamera)

im_height = 1200
im_width = 1600

dwBufferSize = im_height * im_width

pbyteraw = np.zeros((im_height, im_width), dtype=np.uint16)

dwNumberOfByteTrans = 0
dwNumberOfByteTrans = (c_ubyte * dwNumberOfByteTrans)()

dwFrameNo = 0
dwFrameNo = (c_ubyte * dwFrameNo)()

dwMilliseconds = 3000
mydll.StTrg_TakeRawSnapShot(hCamera, 
pbyteraw.ctypes.data_as(POINTER(c_int16)), dwBufferSize*2, 
dwNumberOfByteTrans, dwFrameNo, dwMilliseconds)

print(pbyteraw)
plt.matshow(pbyteraw)
plt.show()

C++ code for taking the image:

DWORD dwBufferSize = 0;
    if(!StTrg_GetRawDataSize(hCamera, &dwBufferSize))
    {
        _tprintf(TEXT("Get Raw Data Size Failed.\n"));
        return(-1);
    }

    PBYTE pbyteRaw = new BYTE[dwBufferSize];
    if(NULL != pbyteRaw)
    {
        DWORD dwNumberOfByteTrans = 0;
        DWORD dwFrameNo = 0;
        DWORD dwMilliseconds = 3000;
        for(DWORD dwPos = 0; dwPos < 10; dwPos++)
        {

            if(StTrg_TakeRawSnapShot(hCamera, pbyteRaw, dwBufferSize, 
&dwNumberOfByteTrans, &dwFrameNo, dwMilliseconds))
        {
            TCHAR szFileName[MAX_PATH];
            if(is2BytesMode)
            {
                _stprintf_s(szFileName, _countof(szFileName), TEXT("%s\\%u.tif"), szBitmapFilePath, dwFrameNo);
                StTrg_SaveImage(dwWidth, dwHeight, STCAM_PIXEL_FORMAT_16_MONO_OR_RAW, pbyteRaw, szFileName, 0);
            }
            else
            {
                _stprintf_s(szFileName, _countof(szFileName), TEXT("%s\\%u.bmp"), szBitmapFilePath, dwFrameNo);
                StTrg_SaveImage(dwWidth, dwHeight, STCAM_PIXEL_FORMAT_08_MONO_OR_RAW, pbyteRaw, szFileName, 0);
            }
            _tprintf(TEXT("Save Image:%s\n"), szFileName);
        }
        else
        {
            _tprintf(TEXT("Fail:StTrg_TakeRawSnapShot\n"));
            break;
        }
    }
    delete[] pbyteRaw;
}

Based on your C code, something like this should work, but it is untested since I don't have your camera library. If you are using 32-bit Python, make sure the library calls are __stdcall to use WinDLL , else use CDLL . 64-bit Python it doesn't matter. Defining the argument types and return type helps catch errors. For output parameters, create instances of the correct ctype, then pass byref() . The way you were currently doing the output parameters was likely the cause of your crash. Setting argtypes would have detected that the values weren't pointers to DWORDs.

from ctypes import *
from ctypes import wintypes as w

mydll = WinDLL('StTrgApi')

mydll.StTrg_Open.argtypes = None
mydll.StTrg_Open.restype = w.HANDLE

mydll.StTrg_GetRawDataSize.argtypes = w.HANDLE,w.PDWORD
mydll.StTrg_GetRawDataSize.restype = None

mydll.StTrg_TakeRawSnapShot.argtypes = w.HANDLE,w.PBYTE,w.DWORD,w.PDWORD,w.PDWORD,w.DWORD
mydll.StTrg_TakeRawSnapShot.restype = None

hCamera = mydll.StTrg_Open()
print(hCamera)

dwBufferSize = w.DWORD()
mydll.StTrg_GetRawDataSize(hCamera,byref(dwBufferSize))

pbyteraw = (w.BYTE * dwbufferSize)()
dwNumberOfByteTrans = w.DWORD() # output parameters.  Pass byref()
dwFrameNo = w.DWORD()           # output parameters.  Pass byref()
dwMilliseconds = 3000

mydll.StTrg_TakeRawSnapShot(hCamera,
                            pbyteraw,
                            dwbufferSize,
                            byref(dwNumberOfByteTrans),
                            byref(dwFrameNo),
                            dwMilliseconds)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM