c++ 为什么我的程序要查找“desktop.bmp”?

nbewdwxp  于 2023-04-08  发布在  其他
关注(0)|答案(1)|浏览(94)

我正在编写一个程序,在这个程序中,我遍历一个包含大约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 boxoutput at the terminal
按下“重试”时,这些是它指向的地方

  1. vector file in the 'include' folder
    1.原始代码的
Mat img_crop;
img_crop = drawing(boundRect[1]);

(也作为注解添加到上述代码中)。
P.S.:我的OpenCV目录直接保存在C:而代码和图像文件夹保存在桌面上。我使用的for循环看起来像这样for (const auto& dirEntry : directory_iterator(image_folder))。我使用的是C++ 20

0sgqnhkj

0sgqnhkj1#

在这段代码中:

for (const auto& dirEntry : directory_iterator(img_path))
{
    string img_name, path = get_stem(dirEntry);
    img_name = path;
    path = img_path + "\\" + img_name + ".bmp";

您放弃文件的扩展名。然后添加.bmp作为扩展名。如果目录中有一个文件不是.bmp文件(例如,在这种情况下隐藏的desktop.ini文件),然后将文件名的扩展名更改为.bmp并尝试打开它,这显然会失败(除非碰巧有一个同名的.bmp)。
在继续之前,你应该检查代码中每个文件的扩展名。你还应该检查条目实际上是一个文件,而不是一个目录。我不知道为什么你要做string img_name, path = get_stem(dirEntry); img_name = path;而不仅仅是string img_name = get_stem(dirEntry);
修复这些提供:

std::filesystem::path img_path = "C:\\Users\\TheHiredGoon\\Desktop\\image_folder"
for (const auto& dirEntry : directory_iterator(img_path))
{
    if (!dirEntry.is_regular_file() || dirEntry.path().extension() != ".bmp")
    {
        continue;
    }
    string img_name = get_stem(dirEntry);
    auto path = img_path / dirEntry.path();

请注意,这将只接受.bmp,而不是.Bmp.BMP,如果你想修复,你可以转换扩展名为小写或使用boost::iequals

相关问题