Mã C++ xuất hiện ok, ở chỗ điều này tạo ra một gói ma trận cho dữ liệu hình ảnh được cung cấp, giả sử bộ đệm ở định dạng RGB8 thông thường. Lưu ý rằng hàm tạo này thực hiện không sao chép bộ đệm, do đó bộ đệm phải còn hiệu lực trong khoảng thời gian của phiên bản Mat
này (hoặc được sao chép).
Mat newImg = Mat(nImageHeight, nImageWidth, CV_8UC3, ptrImageData);
Có vẻ như sự cố nằm trong mã C# của bạn. Tôi không phải là nhà phát triển C#, nhưng tôi sẽ cố hết sức để giúp đỡ. Bạn đang tạo một luồng bộ nhớ và sử dụng codec JPEG để viết một phiên bản nén của hình ảnh vào bộ đệm như thể nó là một tập tin.Nhưng đó là không phải là định dạng dữ liệu mà cv::Mat
đang chờ đợi, vì vậy, về cơ bản bạn sẽ thấy rác (dữ liệu nén được hiểu là không nén).
Với trường hợp System.Image.Drawing.Image
, bạn có thể tạo đối tượng trực tiếp Bitmap
trực tiếp (hoặc có thể sử dụng as
, vì đây là thao tác đơn giản). Sau đó, bạn chỉ có thể sử dụng phương thức Bitmap.LockBits()
tog lấy con trỏ đến dữ liệu hình ảnh cơ bản.
Bitmap bmp = new Bitmap(sourceImage);
// Lock the bitmap's bits.
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] rgbBuffer = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbBuffer, 0, bytes);
// Do your OpenCV processing...
// ...
// Unlock the bits.
bmp.UnlockBits(bmpData);
và sau đó bạn có thể chuyển rgbBuffer
sang OpenCV.
Tôi không tin rằng việc quản lý bộ nhớ trong mã ban đầu là hoàn toàn chính xác, nhưng dù sao ở trên sẽ làm việc cung cấp phạm vi quyền sở hữu bộ đệm nằm trong các cuộc gọi khóa và mở khóa. Nếu dữ liệu hình ảnh vượt quá khối mã này, bạn sẽ phải sao chép bộ đệm.
Hãy cẩn thận với định dạng pixel của bạn - bạn cần đảm bảo rằng phiên bản Image/Bitmap
thực sự chứa dữ liệu RGB8. OpenCV's cv::Mat
có nhiều cờ để bạn có thể làm việc với nhiều định dạng hình ảnh trong bộ nhớ khác nhau. Nhưng lưu ý rằng đây là không phải giống như định dạng trên đĩa (thường được nén), chẳng hạn như PNG, TIFF, v.v.
Tôi nghĩ rằng mã C++ của bạn có một số sai lầm, Mat newImg (...), hoặc Mat * newImg = new Mat (..), ghi của bạn không phải là kiểu C++. – Healer
@healer .. mã đúng. Trong đoạn mã trên, 'newImg' đang được khởi tạo bằng cách sử dụng hàm tạo' tường minh 'của lớp' Mat'. – sgarizvi
Vui lòng cung cấp mã chi tiết hơn, như cách bạn hiển thị hình ảnh, bố cục của 'ptrImageData' là gì. – luhb