01/10/2018, 10:58

OpenCV: Kích thước ảnh (cv::Mat) sai khi load từ file

Mình đang thử đọc dữ liệu của ảnh, hàm đọc mình sử dụng là:

this->img = cv::imread(fileName, cv::IMREAD_UNCHANGED);

Khi đọc xong và show ảnh ra thì không có vấn đề gì:

cv::imshow("img", img);

Ảnh hiển thị đúng kích thước
Tuy nhiên khi dùng hàm get size thì lại bị sai kích thước:
VD: Ảnh của mình là 180x180 px

img.cols => 236px
img.rows => 236px

Dữ liệu parse từ loop rows và cols (mấy dòng cuối)
// Do mình dùng phép so sánh nếu RGBA = {0,0,0,0} thì sẽ break nên Y ~ 180 chứ đúng là ~235

X, Y: R, G, B, A
235, 168: 254,254,254,254
235, 169: 254,254,254,254
235, 170: 254,254,254,254
235, 171: 254,254,254,254
235, 172: 254,254,254,254
235, 173: 254,254,254,254
235, 174: 254,254,254,254
235, 175: 254,254,254,254
235, 176: 254,254,254,254
235, 177: 1,0,0,0

Nhìn phía trên thì thấy nó có tận 236px, lớn hơn kích thước gốc là 180px

Khi mình vẽ ảnh ra trình duyệt thì nó như sau:

Tuy nhiên nếu khởi tạo 1 bức ảnh bằng phương pháp thủ công (cv::Scalar) thì lại cho kích thước cols và rows chuẩn xác:

  this->img = cv::Mat(                              
    cv::Size(80, 80),                        
    CV_8UC4,                                        
    cv::Scalar(color.b, color.g, color.r, color.a)  
    );                                              
// Get data
this->img.cols == 80
this->img.rows == 80

Không biết sai chỗ nào nữa, code hiện tại mình đặt tại link phía dưới:
https://github.com/HadesD/PicToChar/blob/master/src/RgbaPng.cpp

viết 13:05 ngày 01/10/2018

xài lodepng cho nó nhẹ và lành

lodepng::decode(image, width, height, filename);

viết 13:00 ngày 01/10/2018

rảnh rỗi ngồi optimize cái code C# này sang C++ luôn đi nè: https://codegolf.stackexchange.com/a/22326 tạo ra ảnh đẹp lắm

Dark.Hades viết 13:06 ngày 01/10/2018

Tại thấy thằng OCV này nó cơ động nên e liều vọc thử chút, ai dè đau đầu khoản size này

Ban đầu định xài libpng mà nó thuần C nên hơn ngán :))

Không còn cách nào cứu vãn cho thằng OpenCV kia nhỉ, e search trên google mà cũng không ra kq

viết 13:03 ngày 01/10/2018

chờ người rành OpenCV thôi mình ko rành

Văn Dương viết 13:09 ngày 01/10/2018

Sao không dùng IplImage và cvLoadImage ??

Dark.Hades viết 13:02 ngày 01/10/2018

Đã giải quyết xong:

Vấn đề mình mắc phải là do sử dụng cv::Vec4b để lấy đủ 4 màu RGBA, nó sẽ cần tới 3 chiều x, y, z tuy nhiên code getColorAt mình mới chỉ cho vào 2 chiều, nên matrix bị sai.

@Duong_Act E quen dùng API của C++ nên hơi ngại quản lí bộ nhớ của thằng C, tìm hiểu trên mạng thì họ cũng khuyên nên dùng API của C++, với thằng IplImage nó thực ra cũng lấy dữ liệu từ cv::Mat (trên C++)

Văn Dương viết 13:12 ngày 01/10/2018

Opencv mới đầu được viết bằng C. Sau này mới được viết bằng C++. Nên chắc không có chuyện IplImage lấy gì từ Mat. Ngược lại thì có thể.

Nhìn cái hình bạn show bị kẻ sọc là biểu hiện của 99% là tải sai định dạng ảnh.

Dark.Hades viết 13:14 ngày 01/10/2018

API mới của OpenCV thì nó đều xử lí về cv::Mat hết rồi bác

Cái hình bị kẻ sọc đấy là e ghi sang HTML nên nó thành như vậy thôi, thực ra hình bên phải mới đúng:
https://github.com/HadesD/PicToChar/blob/master/src/main.cpp#L48

Văn Dương viết 13:11 ngày 01/10/2018

Opencv mới viết bằng C++ hình như lược bỏ rất nhiều tính năng so với bản viết bằng C thì phải.

Dark.Hades viết 13:12 ngày 01/10/2018

Nó vẫn đảm bảo tính đồng bộ ngược, vẫn dùng cả 2 cùng lúc đc.

Thế nên thằng Mat vẫn xài IplImage đc và ngược lại. Tuy nhiên code C++ thì xài luôn C++ cho an toàn

Bài liên quan
0