我有一臺IP攝像機,它在UDP/RTP中傳輸JPEG壓縮數據。我使用Boost Asio來接收數據。我知道我已經收到了正確的數據,因爲我使用Wireshark檢查了每個數據包的標題信息。將從IP攝像機接收到的JPEG數據流解碼爲C++中的RGB圖像
#include <boost/asio.hpp>
#define MAX_BYTES 1500
using boost::asio::ip::udp;
int main(){
boost::asio::io_service io_service;
udp::socket socket(io_service , udp::endpoint(udp::v4(),50242));
char data[MAX_BYTES];
size_t bytes_received = 0;
while(true){
bytes_received = socket.receive(boost::asio::buffer(data,MAX_BYTES));
}
}
我接收的總的1452個字節的每個分組,其中前20個字節是RTP報頭(12個字節),接着JPEG報頭(8個字節)。剩餘的1432個字節包含有效載荷。假設每個幀由145個數據包組成(frm_pckts = 145)。排序報文後我將它們存儲在緩衝器中用於單個幀如下:
unsigned char* buffer = (unsigned char*) malloc(frm_pckts * 1432 * sizeof(unsigned char);
memcpy(&buffer[packet_index*1432] , &data[20], 1432);
如果我這個緩衝器複製到一個OpenCV的墊,並顯示它會顯示無用值。我也試過
cv::Mat img = cv::imdecode(frame, CV_LOAD_IMAGE_COLOR);
但它也沒有工作。我看到了所有可能的解決方案,我可以在這個網站上找到,但沒有人爲我工作。有沒有可用於將此緩衝區傳遞給其中一個函數並檢索JPEG幀的庫?另外,爲了解碼幀,我還應該在緩衝區中包含頭字節?如果是,哪個頭? JPEG標頭,RTP標頭還是兩者?
我非常感謝任何有用的解決方案或建議。
您究竟如何整理數據包?這可能是你問題的根源。 –
你必須在傳遞給'cv :: imdecode()'的緩衝區中包含JPEG頭文件。它必須能夠知道圖像的格式,所以它需要標題。作爲您正確接收圖像的第一個測試,將其保存到文件並嘗試使用任何JPEG查看器打開該文件。作爲另一個測試,我建議使用'cv :: imdecode()'來創建一個小程序,用它解碼JPEG文件,以查看您是否正確使用API。 – zett42
感謝您的回覆。我不認爲排序有任何問題,因爲我根據從RTP頭獲得的時間戳和序列號對數據包進行排序。 –