zeng
April 28, 2021, 7:56am
1
My call in c++:
long g_nPort;
cv::Mat g_BGRImage;
void CALLBACK DecCBFun(long nPort, char* pBuf, long nSize, FRAME_INFO* pFrameInfo, long nUser, long nReserved2)
{
if(pFrameInfo->nType == T_YV12)
{
if(g_BGRImage.empty())
{
g_BGRImage.create(pFrameInfo->nHeight, pFrameInfo->nWidth, CV_8UC3);
}
cv::Mat YUVImage(pFrameInfo->nHeight + pFrameInfo->nHeight/2, pFrameInfo->nWidth, CV_8UC1, (unsigned char*)pBuf);
cvtColor(YUVImage, g_BGRImage, cv::COLOR_YUV2BGR_YV12);
imshow("RGBImage", g_BGRImage);
cv::waitKey(15);
YUVImage.~Mat();
}
}
I want to use pyOpencv to achieve the same function, what should I do?
The parameter pBuf is the data stream returned by yv12;
My python call:
DECODECALLBACK = CFUNCTYPE(None,c_long,c_char_p,c_long,POINTER(FRAME_INFO),c_long,c_long)
@DECODECALLBACK
def g_decode_callback (nPort:c_long, pBuf:c_char_p, nSize:c_long, pFrameInfo:POINTER(FRAME_INFO), nUser:c_long, nReserved2:c_long):
frameInfo = pFrameInfo.contents
#YU12
if frameInfo.nType == T_YV12:
srcImg = np.zeros((frameInfo.nHeight,frameInfo.nWidth,3),dtype=np.uint8)
# print(srcImg)
return 0
kbarni
April 28, 2021, 10:31am
2
Well, cvtColor has Python equivalent:
dstImg = cv2.cvtColor(srcImg,cv2.COLOR_YUV2BGR_YV12)
cv2.imShow("RGBImage",dstImg)
cv2.waitKey()
berak
April 28, 2021, 11:15am
3
if the question was:
“how to get the p_char_p into a numpy array”
then numpy.fromBuffer (followed by a reshape()) might solve it
zeng
April 29, 2021, 1:37am
4
Yes, I have tried like this:
DECODECALLBACK = CFUNCTYPE(None,c_long,c_char_p,c_long,POINTER(FRAME_INFO),c_long,c_long)
@DECODECALLBACK
def g_decode_callback (nPort:c_long, pBuf:c_char_p, nSize:c_long, pFrameInfo:POINTER(FRAME_INFO), nUser:c_long, nReserved2:c_long):
frameInfo = pFrameInfo.contents
#YU12
if frameInfo.nType == T_YV12:
buf_arr = np.array(pBuf)
arr_val = np.frombuffer(buf_arr,dtype=np.uint8).reshape((frameInfo.nWidth,frameInfo.nHeight))
print(arr_val)
return 0
But it returns the following error:
Traceback (most recent call last):
File "_ctypes/callbacks.c", line 232, in 'calling callback function'
File "E:\python_coding\QtGUIDemo\source\camera\HKPlay.py", line 40, in g_decode_callback
arr_val = np.frombuffer(buf_arr,dtype=np.uint8).reshape((frameInfo.nWidth,frameInfo.nHeight))
ValueError: cannot reshape array of size 12 into shape (1920,1080)
The data returned by pBuf is not equal in size, so I don’t know how to deal with it
berak
April 29, 2021, 7:04am
5
if this is an ip cam, packets will get fragmented along the way.
you probably have to look at c_long
and accumulate / concat buffers, until you have a full yuv image
zeng
April 30, 2021, 3:18am
6
@berak
Yes, this is an ip cam,
How should I distinguish the data length of audio and video, this c_long contains the size of audio
berak
April 30, 2021, 8:30am
7
so, please ignore last remark, since i’m wrong about c_long
zeng
April 30, 2021, 9:09am
8
@berak
So what I don’t understand is how cv::Mat does it, what do I need to do in python to do it