01/10/2018, 14:54

Giúp tìm lỗi đoạn code C++ thao tác với file bị sai dữ liệu không tìm được nguyên nhân?

Chào các bạn. Mình có 1 đoạn code như bên dưới. Đoạn code này sẽ lưu dữ lieu một bức ảnh từ camera xuống file binary rồi đọc trở lại nhưng gặp lỗi không tìm được nguyên nhân.

// đọc dữ lieu từ camera
Camera::getLastFrame();
cv::Mat* img_raw = Camera::RawImage;

// đoạn code test copy
//for (int i = 0; i < 6220800; i++) img_restore->data[i]=img_raw->data[i];

// lưu xuống file.
//mảng dữ lieu của ảnh được trỏ bởi con trỏ data (unsigned char*), độ dài dữ lieu là 6220800 byte (ảnh full HD BGR)
std::fstream filesave;
filesave.open("Programs\Test.aoi", std::ios::out);
filesave.write((char*)img_raw->data, 6220800);
filesave.close();

// nghi ngờ lỗi do máy tính chưa kịp lưu nên đã delay nhưng không có tác dụng
//System::Threading::Thread::Sleep(800);

// đọc dữ lieu từ file vào vùng dữ lieu ảnh của ảnh restore.
std::fstream fileread;
fileread.open("Programs\Test.aoi", std::ios::in);
fileread.read((char*)img_restore->data, 6220800);
fileread.close();

// hiển thị ảnh restore
ShowImage(img_restore);

Hiện trạng lỗi như sau:
Nếu chỉ chạy đoạn code test copy trực tiếp từ img_raw sang img_restore thì ảnh restore hiển thị OK như sau:

Tuy nhiên nếu bỏ đoạn test copy và chạy đoạn code save / read thì ảnh sau khi restore bị sai. Nó going như khi xem đĩa bị vấp hình.

Có một chi tiết them là nếu mình chỉnh sửa vào tất cả các byte của dữ liệu ảnh img_raw thì ảnh sau khi đọc lại đúng.

Khích lệ các anh em sẽ có 50K thẻ nạp cho ai có solution

Tao Không Ngu. viết 17:07 ngày 01/10/2018

Hi Văn Dương
Có thể img_raw của bạn là vùng nhớ buffer mà camera đẩy vào. Bạn cần copy nó ra một vùng nhớ khác để lưu xuống.

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

Vùng nhớ này của camera nhưng chỉ được update khi mình ra lệnh cho camera read thôi. Đây là mình đơn giản hoá ý tưởng thôi. Mình có copy ra nhưng vẫn bị như vậy.

Tao Không Ngu. viết 16:58 ngày 01/10/2018

Hi Văn Dương,

  1. Bạn thử copy vùng nhớ cam mera ra một chỗ khác (Chắc chắn không phải do buffer anh).
  2. Hiển thi vung nhớ đó.
  3. Lưu vùng nhớ đó xuống.
  4. Giải phóng bộ bộ nhớ hoặc viết 1 chương trình khác để mở ảnh. Từ đó xác định lỗi ở khâu nào đọc từ cam, lưu anh, mở anh.

P/S Bạn có thể lưu thành file PPM và đọc lện bằng tool khác để kiểm tra.

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

thử thêm flag binary cho stream xem:

{
    std::ofstream fout("...", std::ios::binary); //open file ở ctor luôn cho đúng RAII, cũng ko cần flag out ở đây vì đây là ofstream
    fout.write(...);
} //khỏi cần gọi fout.close(), dtor của fout sẽ lo việc đó
{
    std::ifstream fin("...", std::ios::binary); //open file ở ctor luôn cho đúng RAII, cũng ko cần flag in ở đây vì đây là ifstream
    fin.read(...);
} //khỏi cần gọi fin.close(), dtor của fin sẽ lo việc đó

thêm chi tiết nữa là C++ đừng xài C style cast (char*) mà xài C++ static_cast:

fout.write(static_cast<char*>(static_cast<void*>(img_raw->data)), 6220800);
Văn Dương viết 17:05 ngày 01/10/2018

Thực tế mình sẽ lưu ảnh khác chứ không phải của camera. Ảnh camera chỉ tượng trưng thôi. Mình đã kiểm tra đến sau bước lưu thì dữ liệu ảnh raw vẫn đúng.
Kiểm tra dung lượng file chính xác.
Mình có xem binary của file tương đối chính xác, chỉ tương đối vì file lưu lượng lớn mình chỉ check sơ bộ bằng tool tự viết.

Mình sẽ check kỹ hơn xem sao.

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

Mình quên mất ios::binary.
Để mai mình kiểm tra lại. Hôm nay về nhà mất rồi

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

Cảm ơn @Phong_Ky_Vo và @tntxtnt đã trợ giúp.

Mình đã test lại và lỗi là do thiếu std::ios::binary option trong khi mở file.
Tìm hiểu them mình được biết là do thiếu ios::binary nên trong lượng dữ lieu rất lớn của mình rất dễ gặp các đoạn dữ lieu đặc biệt như '\n", “\r”… và nó sẽ bị xử lý trước khi lưu file và đọc file làm dữ lieu thu được bị hỏng.


Solution là của bạn @tntxtnt. Bạn inbox cho mình số điện thoại để mình thực hiện lời hứa nhé.

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

Còn một vấn đề nhỏ mình nhờ các bạn chỉ giáo đỡ phải mở chủ đề mới.
Mình có 2 object, một object chứa một function pointer, một object khác chứa một method. Mình sẽ gán như thế nào để 2 đứa “qua lại” với nhau.

class A{
    public:
    typedef void(*Callback)(int data);
    Callback* MyCallback;
}

class B{
    public:
    void MyMethod(int data){}
}

A *a = new A();
B *b = new B();

// bây giờ sẽ như thế nào để thể hiện ý định sau.
A->MyCallback = B->MyMethod;
viết 17:01 ngày 01/10/2018

thôi có thiếu mỗi cái binary flag mà 50k gì =)

câu hỏi mới khó quá, lập thớt khác đi

dễ nhất là xài C++11 std::function, nhưng mà nó chậm, ko biết chậm bao nhiêu, nếu hàm này gọi 1 2 lần chứ ko phải gọi 10000 lần thì ok:

#include <iostream>
#include <functional>

struct A {
    using Callback = std::function<void(int)>;
    Callback myCallback = nullptr;
};
struct B {
    void myMethod(int data) { std::cout << "B's method\n"; }
};

int main()
{
    A a;
    B b;
    a.myCallback = [&b](int data) { b.myMethod(data); };
    a.myCallback(1);
}

cách khác ko xài C++11, hơi bị sai sai vì Callback bị gắn chết là B method :V

#include <iostream>

struct B; //forward declaration
struct A {
    typedef void(B::*Callback)(int); //Callback is a B method
    Callback myCallback = NULL;
};
struct B {
    void myMethod(int data) { std::cout << "B's method\n"; }
};

int main()
{
    A a;
    B b;
    a.myCallback = &B::myMethod;
    (b.*a.myCallback)(2);
}
Tao Không Ngu. viết 17:02 ngày 01/10/2018

HI Văn Dương.
Trong lớp A có 1 con trỏ lớp B. Khi gọi hàm của A thì gọi lại hàm của B.

viết 16:54 ngày 01/10/2018

cái này gọi là pimpl (pim pồ), muốn cho nó đúng với mọi hàm thì nó hơi bị phức tạp 1 tí vì vướng mấy cái const :V http://en.cppreference.com/w/cpp/language/pimpl

ví dụ:

#include <iostream>

struct B;
struct A {
    B* b = nullptr;
    explicit A(B* b) : b{b} {}
};
struct B {
    void f()const { std::cout << "B hello const\n"; }
    void f() { std::cout << "B hello\n"; }
};

int main()
{
    B b;
    const A a(&b);
    a.b->f(); //in ra "B hello" chứ ko phải "B hello const", mặc dù a là const
}

cần phải xài thêm std::experimental::propagate_const: http://coliru.stacked-crooked.com/a/0e8c8cce1333b5fc, mà cái này compiler có compiler ko :V

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

Mình đã ăn hành với cái lỗi này suốt 1 ngày trong khi deadline sát đít. Nên cái flag nó có ý nghĩa không nhỏ.
Đừng ngại nhé, inbox để mình thực hiện lời hứa (tại dung bankplus phải có sđt để chuyển tiền )

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

Vấn đề mình nhờ về sau là nó như hình này:

Bên trái là style của C. Tức là Function pointer và method là static. Và nó chạy.

Còn bên phải là style C++. Khác ở chỗ function pointer và method được di chuyển vào 2 object. Nhưng lỗi.

Mình muốn làm giống delegate trong C#.
Mở rộng ra là làm going event của C#.

Tao Không Ngu. viết 16:56 ngày 01/10/2018

Hi Văn Dương.

stackoverflow.com
SirYakalot

What is a C++ delegate?

c++, delegates, delegation
asked by SirYakalot on 02:18PM - 05 Mar 12

Cơ bản thì nó là một dạng đa hình bạn coi các phương thức là dối tượng.

P/S Code của bạn lỗi vì hàm đí là phương thức của đối tượng.

Bài liên quan
0