我正在编写一个程序,在这个程序中,我遍历一个包含大约500张.bmp格式图像的文件夹(例如“151t12_4.bmp”)。我在Visual Studio 2022中使用C++使用OpenCV对图像进行更改(打开、关闭、轮廓、膨胀等)我正在保存图像特征的结果(长度,宽度,黑色像素等)在CSV文件中。一切都工作正常,除了程序试图读取文件夹中的“desktop.bmp”,即使它不存在。
它总是停止运行程序,因为它找不到文件(很明显),所以我重命名了一个文件到desktop.bmp,它工作正常。**这种不寻常的行为的原因是什么,如何修复它?**我尝试使用另一个图像文件夹,但它返回了相同的错误。
我注意到的另一个问题是,该程序保存2项为“desktop.bmp”在CSV文件中,我正在创建.现在,这不是一个问题本身,但我想知道是什么原因导致这一点,以及如何修复它?
下面是我的代码的样子:
#include <opencv2/core/core.hpp>
#include <opencv2/core/types.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <iostream>
#include <math.h>
#include <string>
#include <algorithm>
#include <fstream>
#include <filesystem>
using namespace cv;
using namespace std;
using directory_iterator = filesystem::directory_iterator;
namespace fs = filesystem;
string get_stem(const fs::path& p) { return p.stem().string(); }
int main()
{
fstream image_details;
fstream file1("image_details.csv");
if (!file1.is_open()) {
image_details.open("image_details.csv", ios::out);
image_details << "Image Name, Width, Height \n";
}
else
image_details.open("image_details.csv", ios::app);
string img_path = "C:\\Users\\TheHiredGoon\\Desktop\\image_folder"
for (const auto& dirEntry : directory_iterator(img_path))
{
string img_name, path = get_stem(dirEntry);
img_name = path;
path = img_path + "\\" + img_name + ".bmp";
Mat src = imread(path);
Mat src_grey = imread(path, IMREAD_GRAYSCALE);
Mat thresh;
threshold(src_grey, thresh, 0, 255, THRESH_OTSU | THRESH_BINARY);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(thresh, contours, hierarchy, RETR_TREE, CHAIN_APPROX_NONE);
//sorting the contours by size (descending order)
sort(contours.begin(), contours.end(), [](const vector<Point>& c1, const vector<Point>& c2)
{
return contourArea(c1, false) > contourArea(c2, false);
});
for (int x = 0; x < contours.size(); x++) {
cout << "Size of contour " << x << " = " << contours[x].size() << endl;
}
vector<vector<Point> > contours_poly(contours.size());
vector<Rect> boundRect(contours.size());
int area[20] = {}, perimeter[20] = {};
for (size_t i = 0; i < contours.size(); i++)
{
approxPolyDP(contours[i], contours_poly[i], 3, true);
boundRect[i] = boundingRect(contours_poly[i]);
area[i] = contourArea(contours_poly[i]);
perimeter[i] = arcLength(contours_poly[i], true);
}
Mat drawing = src_grey.clone();
for (size_t i = 0; i < contours.size(); i++)
{
rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 0), 2);
}
Mat img_crop;
img_crop = drawing(boundRect[1]);
// the compiler indicates that the above line is the "Next statement to execute when this thread returns from the current function"
Mat open_img, closed_img;
int morph_size = 2;
// Create structuring element
Mat element = getStructuringElement(MORPH_RECT, Size(2 * morph_size + 1, 2 * morph_size + 1), Point(morph_size, morph_size));
morphologyEx(binary_image, closed_img, MORPH_CLOSE, element, Point(-1, -1), 1);
morphologyEx(closed_img, open_img, MORPH_OPEN, element, Point(-1, -1), 1);
open_img.convertTo(open_img, CV_32FC1);
// For Erosion
erode(open_img, open_img, element, Point(-1, -1), 1);
// For Dilation
dilate(open_img, open_img, element, Point(-1, -1), 1);
//Yes, the same image was eroded and dilated.
image_details << img_name << "," << src.cols << "," << src.rows << "\n";
}
image_details.close();
return 0;
}
该代码适用于文件夹中的所有文件,并给出预期的结果,但它会在目录中查找文件“desktop.bmp”,理想情况下它不应该这样做。下面是我面临的错误的片段。The output dialog box和output at the terminal。
按下“重试”时,这些是它指向的地方
Mat img_crop;
img_crop = drawing(boundRect[1]);
(也作为注解添加到上述代码中)。
P.S.:我的OpenCV目录直接保存在C:而代码和图像文件夹保存在桌面上。我使用的for
循环看起来像这样for (const auto& dirEntry : directory_iterator(image_folder))
。我使用的是C++ 20
1条答案
按热度按时间0sgqnhkj1#
在这段代码中:
您放弃文件的扩展名。然后添加
.bmp
作为扩展名。如果目录中有一个文件不是.bmp
文件(例如,在这种情况下隐藏的desktop.ini
文件),然后将文件名的扩展名更改为.bmp
并尝试打开它,这显然会失败(除非碰巧有一个同名的.bmp
)。在继续之前,你应该检查代码中每个文件的扩展名。你还应该检查条目实际上是一个文件,而不是一个目录。我不知道为什么你要做
string img_name, path = get_stem(dirEntry); img_name = path;
而不仅仅是string img_name = get_stem(dirEntry);
?修复这些提供:
请注意,这将只接受
.bmp
,而不是.Bmp
或.BMP
,如果你想修复,你可以转换扩展名为小写或使用boost::iequals
。