Opencv: Jalur Unicode/Nama File untuk imread dan imwrite

Dibuat pada 27 Jul 2015  ·  3Komentar  ·  Sumber: opencv/opencv

Ditransfer dari 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

Jalur Unicode/Nama File untuk imread dan 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.

Sejarah

Alexander Shishkov pada 12-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 pada 04-04 2012 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 pada 18-05-2012 14:20
-   Target version set to 2.4.0
nn pada 18-03-2014 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
nn pada 19-03-2014 10:48
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. :)
nn pada 19-03-2014 11:20
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 pada 02-04-2014 01:18
-   Target version changed from 2.4.9 to 3.0
auto-transferred imgcodecs feature low

Komentar yang paling membantu

Semua 3 komentar

Masalah pengkodean .... sulit tetapi bukan tidak mungkin

jika Anda memiliki string ini = 'テスト/abc.jpg'
Anda dapat menyandikan sebagai Windows yang menyandikan karakter seperti ini ->
print('テスト/abc.jpg'.encode('utf-8').decode('unicode-escape'))
Dan Anda mendapatkan sesuatu seperti ini = 'テスト/abc.jpg'

Kemudian jika Anda ingin membaca file dan membuat nama file dapat dibaca dan digunakan, Anda dapat menggunakan beberapa perpustakaan untuk membaca nama file jalur Anda dan kemudian mengubah penyandian ->
#fname is like 'テスト/abc.jpg'
fname.encode('iso-8859-1').decode('utf-8')) # Ini hasil string awal Anda = 'テスト/abc.jpg'

Tim inti OpenCV membahas masalah tersebut pada pertemuan mingguan dan memutuskan untuk tetap konservatif dan tidak memperkenalkan panggilan API baru dengan wchar_t , wstring dan tipe string lainnya Dengan alasan berikut:

  • Sebagian besar pustaka decoding dan encoding gambar menggunakan panggilan fopen standar untuk membuka file dan dukungan wchar_t tambahan memerlukan modifikasi pustaka domain
  • Linux modern, Mac OS dan rilis Windows terbaru mendukung pengkodean UTF-8 yang memungkinkan untuk menggunakan std::string sebagai wadah untuk meneruskannya ke fungsi OpenCV.
  • FS populer di Linux tidak menggunakan wchar_t secara native dan kelebihan beban bukanlah solusi lintas platform.

Ada 2 alternatif untuk menggunakan string wchar_t dengan OpenCV:

  1. Ubah string wchar_t menjadi UTF-8 dan teruskan string UTF-8 sebagai parameter cv::imread dan cv::imwrite . String UTF-8 ditangani oleh panggilan sistem fopen dan perilakunya tergantung pada dukungan OS dan lokal. Lihat mbstowcs dalam standar C++ untuk lebih jelasnya.

  2. OpenCV menyediakan fungsi cv::imdecode dan cv::imencode yang memungkinkan untuk mendekode dan mengkodekan gambar menggunakan buffer memori sebagai input dan output. Solusinya memisahkan file IO dan decoding gambar dan memungkinkan untuk mengelola string jalur, lokal, dll dalam kode pengguna. Lihat cuplikan kode untuk cv::imencode di bawah. fopen dapat diganti dengan _wfopen untuk dukungan string lebar. Lihat manual referensi Microsoft untuk detailnya: 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();
}
Apakah halaman ini membantu?
0 / 5 - 0 peringkat