Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

opencv imread() on Windows for non-ASCII file names

We have an OpenCV problem of opening (and writing) file paths that contain non-Ascii characters on Windows. I saw questions OpenCV imread with foreign characters and imread(openCV),QString unicodes but still didn't understand a proper way of solving the problem.

As far I as I saw in the OpenCV source code, it uses fopen even on Windows (instead of _wfopen) and afaik fopen does not handle non-ascii characters on Windows. From the questions above I saw that there could be some trick using QStrings, but if it works what does it exactly do? How does it transform a unicode string to a character array that will be accepted by Windows' fopen()?

P.S. We don't use QT

Thanks in advance!

like image 640
Vyacheslav Avatar asked Jul 15 '14 23:07

Vyacheslav


2 Answers

The way to do this without hacking the OpenCV source code is to use _wfopen (as Remy suggested) to read the whole file into a memory buffer. Then use OpenCV's function imdecode to create a cv::Mat from that buffer.

You can do the reverse too, if necessary - i.e. use imencode to write an image to a memory buffer, then use _wfopen to open a file with a UNICODE name and write the buffer to it (alternatively, you could just imwrite to a temporary file and then move/rename it using the appropriate API function).

like image 124
Roger Rowland Avatar answered Oct 17 '22 20:10

Roger Rowland


Try this:

cv::Mat ReadImage(const wchar_t* filename)
{
    FILE* fp = _wfopen(filename, L"rb");
    if (!fp)
    {
        return Mat::zeros(1, 1, CV_8U);
    }
    fseek(fp, 0, SEEK_END);
    long sz = ftell(fp);
    char* buf = new char[sz];
    fseek(fp, 0, SEEK_SET);
    long n = fread(buf, 1, sz, fp);
    _InputArray arr(buf, sz);
    Mat img = imdecode(arr, CV_LOAD_IMAGE_COLOR);
    delete[] buf;
    fclose(fp);
    return img;
}
like image 4
hosseinkhosravi Avatar answered Oct 17 '22 20:10

hosseinkhosravi