http://code.opencv.org/issues/1268 ์์ ์ด์ ๋จ
|| Richard Steffen on 2011-07-29 13:28
|| Priority: Low
|| Affected: None
|| Category: highgui-images
|| Tracker: Feature
|| Difficulty:
|| PR:
|| Platform: None / None
Currently, the imread and imwrite method only supports std::string as an input. This isn't working with non-ascii directories/paths. Therefore, the a software depends on OpenCV can not guaranty working on all maschines.
- Description changed from Currently, the imread and imwrite method
only supports std::string as an inpu... to Currently, the imread and
imwrite method only supports std::string as an inpu... More
std::string is still capable of storing any unicode name via UTF-8 encoding, and so it's fopen responsibility to handle this UTF-8 name properly. On Mac and Linux I was able to store image into a file with non-ASCII letters using normal cv::imwrite(). I guess, on Windows it will work too, if you save a source file to UTF-8.
- Priority changed from High to Low
- Assignee set to Vadim Pisarevsky
- Status changed from Open to Cancelled
- Target version set to 2.4.0
AFAIK fopen does not support Unicode on Windows and can't be used to open a path with Unicode characters. The UTF-8 string must be converted to UTF-16 and given to _wfopen instead. See ImageMagick's fopen_utf8 wrapper for example code: http://www.imagemagick.org/api/MagickCore/utility-private_8h_source.html#l00103
- Target version changed from 2.4.0 to 2.4.9
- Status changed from Cancelled to Open
One possible workaround for now using Boost and a memory mapped file:
mapped_file map(path(L"filename"), ios::in);
Mat file(1, numeric_cast<int>(map.size()), CV_8S, const_cast<char*>(map.const_data()), CV_AUTOSTEP);
Mat image(imdecode(file, 1));
The downside is that I/O errors cause access violations instead of C++ exceptions. Also don't write to the "file" Mat. :)
Unfortunately the trick of avoiding to store the image file in memory doesn't work with imwrite, as imencode stores the output in a vector with standard allocator specified. If memory is no issue the contents can of course be written to file using Boost afterwards.
- Target version changed from 2.4.9 to 3.0
IMHO ์ด๊ฒ์ ๋ฌธ์์ ์ง์ ๋์ด์ผ ํฉ๋๋ค. ์ฌ๊ธฐ http://docs.opencv.org/master/d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56 ๋ฐ ์ฌ๊ธฐ http://docs.opencv.org/master/d4/da8/group__imgcodecs .html#gabbc7ef1aa2edfaa87772f1202d67e0ce.
์ธ์ฝ๋ฉ ๋ฌธ์ .... ์ด๋ ต์ง๋ง ๋ถ๊ฐ๋ฅํ์ง๋ ์์ต๋๋ค.
์ด ๋ฌธ์์ด์ด ์๋ ๊ฒฝ์ฐ = 'ใในใ/abc.jpg'
๋ค์๊ณผ ๊ฐ์ด ๋ฌธ์๋ฅผ ์ธ์ฝ๋ฉํ๋ Windows๋ก ์ธ์ฝ๋ฉํ ์ ์์ต๋๋ค. ->
print('ใในใ/abc.jpg'.encode('utf-8').decode('unicode-escape'))
๊ทธ๋ฆฌ๊ณ ๋น์ ์ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ ์ป์ต๋๋ค = 'รฃยยรฃยยนรฃยย/abc.jpg'
๊ทธ๋ฐ ๋ค์ ํ์ผ์ ์ฝ๊ณ ํ์ผ ์ด๋ฆ์ ์ฝ๊ณ ์ฌ์ฉํ ์ ์๊ฒ ํ๋ ค๋ฉด ์ผ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒฝ๋ก์ ํ์ผ ์ด๋ฆ์ ์ฝ์ ๋ค์ ์ธ์ฝ๋ฉ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค ->
#fname is like 'รฃยยรฃยยนรฃยย/abc.jpg'
fname.encode('iso-8859-1').decode('utf-8')) # ์ด๊ธฐ ๋ฌธ์์ด์ ๊ฒฐ๊ณผ = 'ใในใ/abc.jpg'
OpenCV ํต์ฌ ํ์ ์ฃผ๊ฐ ํ์์์ ๋ฌธ์ ๋ฅผ ๋
ผ์ํ๊ณ ๋ณด์๋ฅผ ์ ์งํ๊ณ wchar_t
, wstring
๋ฐ ๊ธฐํ ๋ฌธ์์ด ์ ํ์ผ๋ก ์๋ก์ด API ํธ์ถ์ ๋์
ํ์ง ์๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
fopen
ํธ์ถ์ ์ฌ์ฉํ์ฌ ํ์ผ์ ์ด๋ฉฐ ์ถ๊ฐ wchar_t
์ง์์๋ ๋๋ฉ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ ์ด ํ์ํฉ๋๋ค.std::string
๋ฅผ ์ปจํ
์ด๋๋ก ์ฌ์ฉํ์ฌ OpenCV ๊ธฐ๋ฅ์ ์ ๋ฌํ ์ ์๋ UTF-8 ์ธ์ฝ๋ฉ์ ์ง์ํฉ๋๋ค.wchar_t
๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉฐ ์ค๋ฒ๋ก๋๋ ํ๋ซํผ ๊ฐ ์๋ฃจ์
์ด ์๋๋๋ค.OpenCV์์ wchar_t
๋ฌธ์์ด์ ์ฌ์ฉํ๋ ๋ ๊ฐ์ง ๋์์ด ์์ต๋๋ค.
wchar_t
๋ฌธ์์ด์ UTF-8๋ก ๋ณํํ๊ณ UTF-8 ๋ฌธ์์ด์ cv::imread
๋ฐ cv::imwrite
๋งค๊ฐ๋ณ์๋ก ์ ๋ฌํฉ๋๋ค. UTF-8 ๋ฌธ์์ด์ ์์คํ
fopen
ํธ์ถ์ ์ํด ์ฒ๋ฆฌ๋๋ฉฐ ๋์์ OS ์ง์ ๋ฐ ๋ก์ผ์ผ์ ๋ฐ๋ผ ๋ค๋ฆ
๋๋ค. ์์ธํ ๋ด์ฉ์ C++ ํ์ค์ mbstowcs
๋ฅผ ์ฐธ์กฐํ์ญ์์ค.
OpenCV๋ ๋ฉ๋ชจ๋ฆฌ ๋ฒํผ๋ฅผ ์
์ถ๋ ฅ์ผ๋ก ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง๋ฅผ ๋์ฝ๋ฉํ๊ณ ์ธ์ฝ๋ฉํ ์ ์๋ cv::imdecode
๋ฐ cv::imencode
๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด ์๋ฃจ์
์ ํ์ผ IO์ ์ด๋ฏธ์ง ๋์ฝ๋ฉ์ ๋ถ๋ฆฌํ๊ณ ์ฌ์ฉ์ ์ฝ๋์์ ๊ฒฝ๋ก ๋ฌธ์์ด, ๋ก์ผ์ผ ๋ฑ์ ๊ด๋ฆฌํ ์ ์๋๋ก ํฉ๋๋ค. ์๋ cv::imencode
์ ๋ํ ์ฝ๋ ์ค๋ํซ์ ์ฐธ์กฐํ์ญ์์ค. fopen
๋ ์์ด๋ ๋ฌธ์์ด ์ง์์ ์ํด _wfopen
๋ก ๋์ฒด๋ ์ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ Microsoft ์ฐธ์กฐ ์ค๋ช
์๋ฅผ ์ฐธ์กฐํ์ญ์์ค. 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();
}
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
IMHO ์ด๊ฒ์ ๋ฌธ์์ ์ง์ ๋์ด์ผ ํฉ๋๋ค. ์ฌ๊ธฐ http://docs.opencv.org/master/d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56 ๋ฐ ์ฌ๊ธฐ http://docs.opencv.org/master/d4/da8/group__imgcodecs .html#gabbc7ef1aa2edfaa87772f1202d67e0ce.