2013-02-06 37 views
11

Tôi có bộ đệm unsigned char* chứa dữ liệu của hình ảnh jpeg. Tôi muốn hiển thị hình ảnh đó bằng cách sử dụng C++ và opencv. Nếu tôi làm:opencv đọc hình ảnh jpeg từ bộ đệm

Mat img(Size(640, 480), CV_8UC3, data); 
namedWindow("image", 1); 
imShow("image", img); 

Tôi nhận được một mớ hỗn độn pixel.

Tôi cho rằng đó là do dữ liệu là jpeg (có tiêu đề). Bởi vì công trình này:

Mat imgbuf(Size(640, 480), CV_8UC3, data); 
Mat img = imdecode(imgbuf, CV_LOAD_IMAGE_COLOR); 

NHƯNG tôi không thể sử dụng chức năng imdecode vì nó là từ highgui.h mà là dựa trên GTK 2, và trong dự án của tôi, tôi sử dụng GTK 3.

Vì vậy, làm thế nào tôi có thể hiển thị dữ liệu đệm? Có cách nào để giải mã hình ảnh jpeg khác với imdecode trong opencv, nếu đó là vấn đề. Tôi thực sự không muốn phải xây dựng lại opencv với Qt ...

Bất kỳ đề xuất nào khác?

(Sử dụng Linux)

+2

Bạn không thể sử dụng 'libjpeg' để giải mã và được thực hiện với nó? Vấn đề là gì? – mmgp

+0

@mmgp Tôi sẽ thử libjpeg, chỉ nghĩ rằng tôi có thể làm cùng một điều mà không bao gồm một thư viện khác. – Matekk

+1

opencv sẽ không tải hình ảnh jpeg nếu bạn làm không có 'libjpeg', vì vậy không có thư viện nào khác được đưa vào. – mmgp

Trả lời

4

tôi đã giải nén hình ảnh JPEG sử dụng libjpeg bằng cách sử dụng quy trình chuẩn được mô tả trong libjpeg API documentation trong 'Chi tiết giải nén.

Sau khi giải nén dữ liệu bạn có thể sử dụng để xây dựng cv::Mat. Tâm trí bạn, hình ảnh giải nén ở định dạng RGB, trong khi openCV sử dụng định dạng BGR để hoạt động cvtColor() với định dạng CV_RGB2BGR là cần thiết.

27

Tôi đã thấy nhiều câu trả lời cho câu hỏi này xung quanh trên mạng nói rằng bạn nên gọi libjpeg trực tiếp và bỏ qua thói quen imread() của OpenCV.

Điều này là KHÔNG cần thiết! Bạn có thể sử dụng imdecode() để giải mã bộ đệm hình ảnh thô từ bộ nhớ. Cách để làm điều đó là KHÔNG trực quan, và không được ghi chép đủ để giúp mọi người cố gắng làm điều này lần đầu tiên.

Nếu bạn có một con trỏ/size cho dữ liệu file raw của bạn (fread() trực tiếp từ .jpg, .png, .tif, tác phẩm, vv ...

int nSize = ...  // Size of buffer 
uchar* pcBuffer = ... // Raw buffer data 


// Create a Size(1, nSize) Mat object of 8-bit, single-byte elements 
Mat rawData(1, nSize, CV_8UC1, (void*)pcBuffer); 

Mat decodedImage = imdecode(rawData /*, flags */); 
if (decodedImage.data == NULL) 
{ 
    // Error reading raw image data 
} 

Đó là IT!

Hy vọng điều này sẽ giúp ai đó trong tương lai

+0

Nó đã giúp một ai đó. Lưu ý rằng bạn đã sử dụng 'size' thay vì 'nsize' và bạn có thể đã khởi tạo rawData trực tiếp từ hàm tạo. –