Closed opencv-pushbot closed 4 years ago
IMHO this should be specified in the documentation : here http://docs.opencv.org/master/d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56 and here http://docs.opencv.org/master/d4/da8/group__imgcodecs.html#gabbc7ef1aa2edfaa87772f1202d67e0ce.
Encoding issues.... difficult but no impossible
if you have this string = 'テスト/abc.jpg'
You can encode as Windows encoding the characters like this->
print('テスト/abc.jpg'.encode('utf-8').decode('unicode-escape'))
And you get something like this = 'ãã¹ã/abc.jpg'
Then if you want to read the file and get the filenames readable and usable, you can use some library to read the filenames of your path and then change the encoding->
#fname is like 'ãã¹ã/abc.jpg'
fname.encode('iso-8859-1').decode('utf-8')) # This result of your initial string ='テスト/abc.jpg'
OpenCV core team discussed the problem on weekly meeting and decided to stay conservative and do not introduce new API calls with wchar_t
, wstring
and other string types By the following reasons:
fopen
call to open files and extra wchar_t
support requires domain libraries modificationstd::string
as container to pass it to OpenCV functions.wchar_t
natively and the overloads are not cross platform solution.There are 2 alternatives to use wchar_t
strings with OpenCV:
Convert wchar_t
strings to UTF-8 and pass UTF-8 string as cv::imread
and cv::imwrite
parameter. UTF-8 string is handled by system fopen
call and it's behavior depends on OS support and locale. See mbstowcs
in C++ standard for more details.
OpenCV provides cv::imdecode
and cv::imencode
functions that allow to decode and encode image using memory buffer as input and output. The solution decouples file IO and image decoding and allows to manage path strings, locales, etc in user code. See code snippet for cv::imencode
bellow. fopen
can be replaced with _wfopen
for wide strings support. See Microsoft reference manual for details: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen?view=vs-2019
#include <vector>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
int main(int argc, char * argv) { FILE f = fopen("lena.jpg", "rb"); fseek(f, 0, SEEK_END); // seek to end of file size_t buffer_size = ftell(f); // get current file pointer fseek(f, 0, SEEK_SET); // seek back to beginning of file
std::vector<char> buffer(buffer_size);
fread(&buffer[0], sizeof(char), buffer_size, f);
fclose(f);
cv::Mat frame = cv::imdecode(buffer, cv::IMREAD_COLOR);
cv::imshow("Camera", frame);
cv::waitKey();
}
Could we perhaps at least raise an error instead of silently just failing to write?
Raising would be indeed very helpful. I currently have to work with a Windows machine and accidentially a "Umlaut" slipped into my path. Invoking the API by Python I assumed that handling of UTF8 would be handled correctly.
I posted a workaround on stackoverflow, that works flawless with any cv2 method: https://stackoverflow.com/a/78462365/924017
Transferred from http://code.opencv.org/issues/1268
Unicode Path/Filename for imread and imwrite
History
Alexander Shishkov on 2012-02-12 20:47
Vadim Pisarevsky on 2012-04-04 11:58
Andrey Kamaev on 2012-05-18 14:20
n n on 2014-03-18 13:11
n n on 2014-03-19 10:48
n n on 2014-03-19 11:20
Alexander Smorkalov on 2014-04-02 01:18