Opencv: imread ๋ฐ imwrite์˜ ์œ ๋‹ˆ์ฝ”๋“œ ๊ฒฝ๋กœ/ํŒŒ์ผ ์ด๋ฆ„

์— ๋งŒ๋“  2015๋…„ 07์›” 27์ผ  ยท  3์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: opencv/opencv

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

imread ๋ฐ imwrite์˜ ์œ ๋‹ˆ์ฝ”๋“œ ๊ฒฝ๋กœ/ํŒŒ์ผ ์ด๋ฆ„

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.

์—ญ์‚ฌ

Alexander Shishkov 2012-02-12 20:47
-   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
Vadim Pisarevsky 2012-04-04 11:58
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
Andrey Kamaev on 2012-05-18 14:20
-   Target version set to 2.4.0
nn 2014-03-18 13:11์—
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
2014-03-19 10:48์— nn
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. :)
2014-03-19 11:20์— nn
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.
Alexander Smorkalov 2014-04-02 01:18
-   Target version changed from 2.4.9 to 3.0
auto-transferred imgcodecs feature low

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

IMHO ์ด๊ฒƒ์€ ๋ฌธ์„œ์— ์ง€์ •๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ http://docs.opencv.org/master/d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56 ๋ฐ ์—ฌ๊ธฐ http://docs.opencv.org/master/d4/da8/group__imgcodecs .html#gabbc7ef1aa2edfaa87772f1202d67e0ce.

๋ชจ๋“  3 ๋Œ“๊ธ€

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 ์ง€์›์—๋Š” ๋„๋ฉ”์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ˆ˜์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ์ตœ์‹  Linux, Mac OS ๋ฐ ์ตœ์‹  Windows ๋ฆด๋ฆฌ์Šค๋Š” std::string ๋ฅผ ์ปจํ…Œ์ด๋„ˆ๋กœ ์‚ฌ์šฉํ•˜์—ฌ OpenCV ๊ธฐ๋Šฅ์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” UTF-8 ์ธ์ฝ”๋”ฉ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • Linux์˜ ์ธ๊ธฐ ์žˆ๋Š” FS๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ wchar_t ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉฐ ์˜ค๋ฒ„๋กœ๋“œ๋Š” ํ”Œ๋žซํผ ๊ฐ„ ์†”๋ฃจ์…˜์ด ์•„๋‹™๋‹ˆ๋‹ค.

OpenCV์—์„œ wchar_t ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋Œ€์•ˆ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. wchar_t ๋ฌธ์ž์—ด์„ UTF-8๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  UTF-8 ๋ฌธ์ž์—ด์„ cv::imread ๋ฐ cv::imwrite ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. UTF-8 ๋ฌธ์ž์—ด์€ ์‹œ์Šคํ…œ fopen ํ˜ธ์ถœ์— ์˜ํ•ด ์ฒ˜๋ฆฌ๋˜๋ฉฐ ๋™์ž‘์€ OS ์ง€์› ๋ฐ ๋กœ์ผ€์ผ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ C++ ํ‘œ์ค€์˜ mbstowcs ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

  2. 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();
}
์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰