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
xài lodepng cho nó nhẹ và lành
lodepng::decode(image, width, height, filename);
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
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
chờ người rành OpenCV thôi mình ko rành
Sao không dùng IplImage và cvLoadImage ??
Đã 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ềux, 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++)
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.
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
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.
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