Qt程序已退出,代码为-1073741819

Qt程序已退出,代码为-1073741819,qt,opencv,Qt,Opencv,我正在从事一个在Windows7中使用Qt和Opencv的基于人脸识别的项目。我现在遇到了一个真正的死胡同…我需要使用一些图像来训练人脸识别器…但是每当我对train语句进行注释时,程序运行良好,但并不符合我的目的 void Dialog::on_btnAdd_2_clicked() { tmrTimer->stop(); dir=QDir(directory); QFileInfoList files; QFileInfo file; QStri

我正在从事一个在Windows7中使用Qt和Opencv的基于人脸识别的项目。我现在遇到了一个真正的死胡同…我需要使用一些图像来训练人脸识别器…但是每当我对train语句进行注释时,程序运行良好,但并不符合我的目的

void Dialog::on_btnAdd_2_clicked()
{
    tmrTimer->stop();

    dir=QDir(directory);
    QFileInfoList files;
    QFileInfo file;
    QString filen;


    dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
    files=dir.entryInfoList();
    int nofiles;
    nofiles=files.size();
    for(int i=0;i<nofiles;i++)
    {
        file=files.at(i);
        filen=file.absoluteFilePath();


        std::string fname = filen.toStdString();

        filen=file.baseName();
        std::string filename=filen.toStdString();

        char* path = new char [fname.size()+1];
        char name[10];

        strcpy(name,filename.c_str());
        strcpy( path, fname.c_str() );

        name[1]='\0';

        ui->boxConsole->appendPlainText(path);
        ui->boxConsole->appendPlainText(name);

        cv::Mat temp=cv::imread(path,-1);
        newImages.push_back(temp);
        newLabels.push_back(atoi(name));
    }


    ui->boxConsole->appendPlainText("Training Started....!!");

    cv::Ptr<cv::FaceRecognizer> model = cv::createEigenFaceRecognizer();

    model->train(newImages,newLabels);   ///training statement

    //strcat(home,"\\data.xml");


    //model->save(home);


    ui->boxConsole->appendPlainText("Training Completed!!");
    tmrTimer->start();
}
我根据建议修改了代码如下…并遇到了另一个问题

void Dialog::on_btnAdd_2_clicked()
{
    tmrTimer->stop();

    dir=QDir(directory);
    QFileInfoList files;
    QFileInfo file;
    QString filen;

    char name[10];
    int i,j;
    std::string str;


    dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
    files=dir.entryInfoList();
    int nofiles;
    nofiles=files.size();

    for(i=0;i<nofiles;i++)
        {
            file=files.at(i);
            filen=file.baseName();
            std::string filename=filen.toStdString();
            strcpy(name,filename.c_str());

            for(j=0;name[j]!='-';j++);
            name[j]='\0';

            filen=file.absoluteFilePath();
            str=filen.toStdString();

            cv::Mat offimage=cv::imread(str.c_str(),-1);

            cv::namedWindow("face",WINDOW_AUTOSIZE);     //show retrieved image in a window
            cv::imshow("face",offimage);
            cvvWaitKey(1000);

            newImages.push_back(offimage);
            newLabels.push_back(atoi(name));


        }

当代码崩溃时,使用调试器找出崩溃的位置。如果您不理解原因,请将回溯添加到问题

我假设在文件上循环时,文件名处理会导致崩溃。 您使用char*而不是std::string或QString打开了多个蠕虫罐头,但操作不当

这一次,这是非常不安全的,也是不安全的缓冲区溢出:

    char name[10];
    ...
    strcpy(name,filename.c_str());
如果文件名长于9,则行为很可能是未定义的崩溃

您也在泄漏内存,因为这个分配永远不会被释放:char*path=new char[fname.size+1]

因此,我强烈建议使用QString而不是摆弄char*。如果需要将char*传递给OpenCV,可以这样做:

const QByteArray ba = filename.toLatin1(); //or toUtf8(), toLocal8Bit(), depending on the encoding you need
... functionTakingChar( ba.constData(), -1 ); // or .data(), if imread() takes a non-const char
imread接受std::字符串,因此:

... imread( filename.toStdString(), -1 );

我检查了所有其他内容,但导致错误的语句是model->train call…我已尽可能简短地命名了文件…我需要使用指定路径中的图像对其进行训练…我还创建了要在gui中提供的显示框中打印的名称,以便确保标签字段没有错误…感谢您的建议:-正如您所说,我已经更改了…现在它显示了一些其他错误:传递给C运行时函数的参数无效。传递给C运行时函数的参数无效。OpenCV错误:图像步骤错误矩阵不连续,因此其行数不能在重塑中更改,文件C:\OpenCV\modules\core\src\matrix.cpp,第801行在抛出“cv::Exception”实例后终止调用什么:C:\OpenCV\modules\core\src\matrix.cpp:801:Error:-13矩阵不连续,因此,它的行数不能在函数整形中更改。您如何调用imread?我看到它需要一个std::字符串,所以我扩展了答案。否则,尝试在抛出时设置一个捕获点,以查看引发异常的bactrace。我只是对函数进行了建模并更新了问题。。现在它的显示错误:OpenCV错误:图像步骤错误矩阵不是连续的,因此它的行数不能在整形中更改,文件C:\OpenCV\modules\core\src\matrix.cpp,第801行………我确定输入图像的尺寸为80*80,,,
const QByteArray ba = filename.toLatin1(); //or toUtf8(), toLocal8Bit(), depending on the encoding you need
... functionTakingChar( ba.constData(), -1 ); // or .data(), if imread() takes a non-const char
... imread( filename.toStdString(), -1 );