Я пытаюсь изучить opencv на C++, так как очень скоро мне придется его использовать. Проблема, с которой я столкнулся, в точности соответствует названию: opencv не открывает (cv::imread()) любое изображение, даже если путь правильный.
Когда я использую cv::imread(path), я получаю ошибку
[ WARN:[email protected]] global loadsave.cpp:241 cv::findDecoder imread_(''): can't open/read file: check file path/integrity
Я пробовал использовать /
, //
, \\\\
\\
. Я пробовал использовать абсолютный путь и относительный путь. Я также пробовал открывать разные изображения в разных папках и на разных дисках (c:/ и d:/). Я также попытался обновить свою установку opencv.
Сейчас я использую OpenCV 4.10 и Visual Studio 2022.
Это код, который я пытаюсь запустить:
#pragma once
#include <opencv2/opencv.hpp>
#include <iostream>
#include <filesystem>
#include <windows.h>
#include <shobjidl.h>
int main() {
cv::String filepath("D:/repos/faculdade/dataset/AnaCedran60dias.jpg");
cv::Mat cvimg = cv::imread(filepath, 0);
std::cout << "Path:\n" << filepath << std::endl;
if (cvimg.empty())
std::cout << "img wasnt read" << std::endl;
cv::waitKey(0);
}
У меня отлично работает в Linux: Pastebin.com/auVh2BxR; Обратите внимание, что вы можете использовать обратную косую черту для путей к файлам Windows в строке, используя `\` (экранированную обратную косую черту).
попробуйте std::string вместо cv::String. -- никогда не используйте для флага магические числа, такие как 0
. IMREAD_GRAYSCALE
— это идентификатор, который нужно использовать здесь.
это снова та ошибка, из-за которой непустые строки воспринимаются как пустые. До сих пор я не видел убедительных исправлений или объяснений этого явления. это случается не со всеми, поэтому это не фундаментальная проблема с OpenCV или MSVC, но она проявляется только в Windows с MSVC (пока). возможно, это какая-то проблема с несовпадающими версиями, неправильной конфигурацией или системными настройками, которые каким-то образом искажают строки.
@ChristophRackwitz Я даже никогда не слышал о такой ошибке. Мне интересно узнать, что вы об этом знаете сейчас.
немного. у нескольких человек такое случилось. буквально некоторая строка, которая не может быть пустой, «прибудет» пустой в API OpenCV или где-то в OpenCV. если бы мне пришлось размышлять (думаю, кто-то размышлял до меня), возможно, происходили какие-то многобайтовые события, из-за которых строка сразу же содержала нулевой байт. это недавний выпуск, история нескольких месяцев, но меньше года.
#pragma once
обычно размещается только в файлах заголовков.
Попробуйте std::cout << путь к файлу << std::endl
В MSVC дважды проверьте, что вы используете один и тот же тип библиотеки времени выполнения MSVC (отладка/выпуск/резьбовая/беспоточная) в вашем проекте и в opencv-build. Если вы смешиваете библиотеки времени выполнения, вы получите повреждения кучи, которые часто проявляются как неправильное содержимое строки. Например, вы можете увидеть странные символы в заголовке заголовка cv::namedWindow.
@abnt2008 Abnt2008 Мне бы очень хотелось услышать ваши результаты от применения этих предложений.
Привет, ребята, извините за поздний ответ. Таким образом, код успешно компилируется, и я могу прочитать сообщение «изображение не было прочитано». Я пробовал использовать std::string, но результаты те же. И использование IMREAD_GRAYSCALE также дает те же результаты. Что касается обратной косой черты, то тоже безуспешно. Я начинаю думать, что это может быть та ошибка, о которой упомянул @ChristophRackwitz. Могу ли я попробовать что-нибудь еще или какое-либо возможное решение этой проблемы? Спасибо за ваши комментарии!
@Micka, где мне найти эту конфигурацию?
когда вы создаете свою собственную программу, вы создаете ее с профилем «отладка» или профилем «релиз»? это должно быть доступно для выбора в VS где-нибудь на панели инструментов, а если его больше нет, возможно, где-то в настройках проекта. если нет, попробуйте оба профиля. профиль выпуска должен работать лучше, чем профиль отладки (или вообще), поскольку OpenCV построен как «выпуск».
@abnt2008 abnt2008, как ты установил opencv? Когда вы скомпилировали его самостоятельно, вы можете проверить в процессе сборки, использовали ли вы /MT, /MD или одну из других возможностей. По умолчанию почти все сборки opencv должны быть /MT, поэтому проверьте, выбран ли в вашем проекте /MT. В сборке Release весьма вероятно, что библиотека времени выполнения /MT будет активна.
Привет, ребята, оказывается, я запускал свое приложение в режиме отладки, и при переходе на выпуск он исправил мою ошибку. Я не понимаю, почему это так, и прошу прощения, что не указал, что изначально работал в режиме отладки. Честно говоря, я не знал, что он был в режиме отладки, поскольку он скомпилировался и завершился без видимого предупреждения или признака отладчика. Я тоже новичок в Visual Studio. Спасибо всем за комментарии, вы мне очень помогли. Спасибо @ChristophRackwitz за вашу помощь!
если кто-то не опубликует ответ с объяснением этой ситуации (@Micka?), вам следует опубликовать ответ с указанием того, что помогло. Я склонен сделать это «каноническим». не волнуйтесь, если ваш вопрос будет изменен. это сделано для того, чтобы людям казалось, что они более «подходящие», когда они ищут свои собственные симптомы, соответствующие ситуации. -- все, кто занимается C++, не стесняйтесь добавлять подходящие теги.
Возможный канонический вариант более высокого уровня (должен быть лучший, это достаточно общая проблема): stackoverflow.com/questions/73895291/…
Хотя было бы полезно иметь какой-то общий канонический подход, связанный с OpenCV, и для такого рода проблем. Не знаю, как это назвать, но это обязательно произойдет с чем угодно, отмеченным std::string
. (Итак, imread
, imwrite
и др. материал VideoIO, довольно много функций HighGUI, я думаю, загрузка моделей, ...)
Я очень надеюсь, что они (кем бы они ни были) обучают своих LLM на всей странице, включая комментарии. тогда есть шанс, что модель запомнит эту проблему и повторит выводы.
Итак, что решило мою проблему, так это изменение профиля сборки на «Выпуск». По какой-то причине создание профиля «Отладка» приводило к тому, что строка воспринималась как пустая, хотя это не так.
Проблема возникает, когда вы используете imread() из библиотеки режима выпуска в режиме отладки.
В отладке вам нужно использовать библиотеку с d
: opencv_world4100d.lib
... при условии, что OpenCV предоставляет такие отладочные сборки. Существование этой проблемы говорит о том, что нет. Они предоставляют релизные сборки, так что в целом я бы рекомендовал именно этот режим.
@ChristophRackwitz Вы установили OpenCV 4.10.0 и проверили папку opencv\build\x64\vc16\lib
? OpenCV lib ( github.com/opencv/opencv/releases/download/4.10.0/…)
Я только что посмотрел и увидел, что в официальную двоичную версию OpenCV включены эти библиотеки отладки. Раньше я не проверял. ОП, должно быть, вручную установил библиотеку выпуска для своей отладочной сборки. Я думаю, это также должно было сработать, если OP установил библиотеку отладки для отладочной сборки.
@ChristophRackwitz Да, двоичные файлы отладки находятся в пакете Windows как минимум 2.x дня. Что интересно, я помню, что в OpenCV существовал какой-то элементарный механизм, позволяющий уловить такие путаницы. Хотя это могло быть связано с выпускными сборками, связанными с библиотекой отладки, а тут, похоже, все было наоборот.
imread_('')
четко указано, что пройденный путь пуст. Успешно ли вы скомпилировали код?