在项目过程中使用opencv时遇到了cv::imread无法读取中文路径的问题。首先思路是先用QIamge对图片进行读取,然后将QImage转换成cv::Mat。
void TemplateImageManager::setTemplateImage(const QString &filePath){ //用QImage读取带中文路径图片 QImage img(filePath); //将img转换成需要的类型 img = img.convertToFormat(QImage::Format_RGB888); //调用QImage2cvMat进行转换,得到cv::mat this->templateImage = QImage2cvMat(img).clone();}QImage2cvMat是将不同格式的QImage转换cv::Mat中对应的格式
cv::Mat TemplateImageManager::QImage2cvMat(QImage image){ cv::Mat mat; switch(image.format()) { case QImage::Format_ARGB32: case QImage::Format_RGB32: case QImage::Format_ARGB32_Premultiplied: mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); break; case QImage::Format_RGB888: mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB); break; case QImage::Format_Indexed8: mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); break; } return mat;}到这里问题就解决了。给大家分享一个我的一点点收获,也是我想记录的东西。 这两个函数中,QImage img 是一个局部变量,而我们用它进行图片读取的时候,图片的数据是由QImage进行管理的,而我们QImage2cvMat中用的是 (void*)image.constBits(),转换出来的mat其实指向的是img的内存,然后我之前用的是 this->templateImage = QImage2cvMat(img) ,这里也是mat之间的浅拷贝,我的this->templateImage指向的是mat的内存地址,也就相当于指向的img的内存。所以由于img是一个局部变量,执行完这个函数之后,QImage便会将内存清空,而此时this->templateImage使用就会出错了,所以后面就采用了this->templateImage = QImage2cvMat(img).clone()来进行深度拷贝,这时候就是直接复制了一份img的内存数据啦,后面就能进行正常访问了。
如果有哪里说的不对的地方,欢迎大家指正。