мой поток видео был сбой при запуске darknet.exe для объекта обнаружения - PullRequest
1 голос
/ 02 мая 2019

Я работаю над проектом углубленного обучения, чтобы обнаружить номерной знак из видеопотока, поэтому я использую darknet (yolov3), opencv 4.1.0 и OCR

В настоящее время проект может обнаружить номерной знак по изображению и обрезать лицензию, а затем отправить его в программу распознавания текста для распознавания текста

Но когда вводится видео или когда я открываю камеру веб-камеры, я получаю сообщение об ошибке при первом обнаружении номерного знака.

это ошибка, которую я получил:

Webcam index: 0
Video stream: 640 x 480
Objects:


FPS:0.0
Objects:


FPS:0.0
Objects:


FPS:8.6
Objects:


FPS:9.7
Objects:


FPS:9.7
Objects:


FPS:8.7
Objects:


FPS:8.6
Objects:


FPS:8.7
Objects:


FPS:9.5
Objects:


FPS:9.1
Objects:


FPS:9.6
Objects:


FPS:9.5
Objects:


FPS:8.7
Objects:


FPS:8.8
Objects:


FPS:9.7
Objects:


FPS:8.8
Objects:


FPS:8.7
Objects:


FPS:8.4
Objects:


FPS:8.9
Objects:


FPS:9.9
Objects:


FPS:9.4
Objects:


FPS:8.6
Objects:


FPS:8.9
Objects:


FPS:9.8
Objects:


FPS:10.1
Objects:


FPS:8.9
Objects:


FPS:9.2
Objects:


FPS:10.0
Objects:


FPS:8.7
Objects:


FPS:9.0
Objects:


FPS:8.6
Objects:


FPS:9.3
Objects:


FPS:8.5
Objects:


FPS:9.8
Objects:


FPS:9.0
Objects:


FPS:10.0
Objects:


FPS:8.9
Objects:


FPS:9.7
Objects:


FPS:9.9
Objects:


FPS:9.2
Objects:


FPS:9.6
Objects:


FPS:8.8
Objects:


FPS:9.2
Objects:


FPS:9.0
Objects:


FPS:9.6
Objects:


FPS:9.8
Objects:


FPS:9.0
Objects:


FPS:8.5
Objects:


FPS:9.0
Objects:


FPS:8.3
Objects:


FPS:8.8
Objects:


FPS:9.4
Objects:


FPS:9.0
Objects:


FPS:9.9
Objects:


FPS:9.7
Objects:


FPS:8.9
Objects:


FPS:9.5
Objects:


FPS:9.2
Objects:


FPS:9.0
Objects:


FPS:10.1
Objects:


FPS:9.0
Objects:


FPS:8.9
Objects:


FPS:9.0
Objects:


FPS:10.4
Objects:


FPS:8.9
Objects:


FPS:8.6
Objects:


FPS:9.1
Objects:


FPS:9.1
Objects:


FPS:10.1
Objects:


FPS:9.0
Objects:


FPS:10.0
Objects:


FPS:9.2
Objects:


FPS:8.8
Objects:


matricule: 31%

openCV: terminate handler is called! The last OpenCV error is:
OpenCV(4.1.0) Error: Bad argument (Unknown array type) in cv::cvarrToMat, file C:\build\master_winpack-build-win64-vc14\opencv\modules\core\src\matrix_c.cpp, line 185

Это код matrix_c.cpp, который вызывает ошибку

Mat cvarrToMat(const CvArr* arr, bool copyData,
               bool /*allowND*/, int coiMode, AutoBuffer<double>* abuf )
{
    if( !arr )
        return Mat();
    if( CV_IS_MAT_HDR_Z(arr) )
        return cvMatToMat((const CvMat*)arr, copyData);
    if( CV_IS_MATND(arr) )
        return cvMatNDToMat((const CvMatND*)arr, copyData );
    if( CV_IS_IMAGE(arr) )
    {
        const IplImage* iplimg = (const IplImage*)arr;
        if( coiMode == 0 && iplimg->roi && iplimg->roi->coi > 0 )
            CV_Error(CV_BadCOI, "COI is not supported by the function");
        return iplImageToMat(iplimg, copyData);
    }
    if( CV_IS_SEQ(arr) )
    {
        CvSeq* seq = (CvSeq*)arr;
        int total = seq->total, type = CV_MAT_TYPE(seq->flags), esz = seq->elem_size;
        if( total == 0 )
            return Mat();
        CV_Assert(total > 0 && CV_ELEM_SIZE(seq->flags) == esz);
        if(!copyData && seq->first->next == seq->first)
            return Mat(total, 1, type, seq->first->data);
        if( abuf )
        {
            abuf->allocate(((size_t)total*esz + sizeof(double)-1)/sizeof(double));
            double* bufdata = abuf->data();
            cvCvtSeqToArray(seq, bufdata, CV_WHOLE_SEQ);
            return Mat(total, 1, type, bufdata);
        }

        Mat buf(total, 1, type);
        cvCvtSeqToArray(seq, buf.ptr(), CV_WHOLE_SEQ);
        return buf;
    }
    CV_Error(CV_StsBadArg, "Unknown array type");
}

Это код функции draw_detections_cv_v3 для обнаружения Draw, и я понял, что он блокируется каждый раз, когда достигает этого кода:

 if(copy_img == NULL) copy_img = cvCreateImage(cvSize(b_width,b_height), ipl_im-depth, ipl_im->nChannels);
              cvCopy(show_img, copy_img, 0);

void draw_detections_cv_v3(mat_cv* mat, detection *dets, int num, float thresh, char **names, image **alphabet, int classes, int ext_output)
{
    cv::Mat *show_img = mat;
    int i, j;
    if (!show_img) return;
    static int frame_id = 0;
    frame_id++;

    for (i = 0; i < num; ++i) {
        char labelstr[4096] = { 0 };
        int class_id = -1;
        for (j = 0; j < classes; ++j) {
            int show = strncmp(names[j], "dont_show", 9);
            if (dets[i].prob[j] > thresh && show) {
                if (class_id < 0) {
                    strcat(labelstr, names[j]);
                    class_id = j;
                    char buff[10];
                    sprintf(buff, " (%2.0f%%)", dets[i].prob[j]*100);
                    strcat(labelstr, buff);
                }
                else {
                    strcat(labelstr, ", ");
                    strcat(labelstr, names[j]);
                }
                printf("%s: %.0f%% ", names[j], dets[i].prob[j] * 100);
            }
        }
        if (class_id >= 0) {
            int width = std::max(1.0f, show_img->rows * .002f);

            //if(0){
            //width = pow(prob, 1./2.)*10+1;
            //alphabet = 0;
            //}

            //printf("%d %s: %.0f%%\n", i, names[class_id], prob*100);
            int offset = class_id * 123457 % classes;
            float red = get_color(2, offset, classes);
            float green = get_color(1, offset, classes);
            float blue = get_color(0, offset, classes);
            float rgb[3];

            //width = prob*20+2;

            rgb[0] = red;
            rgb[1] = green;
            rgb[2] = blue;
            box b = dets[i].bbox;
            if (std::isnan(b.w) || std::isinf(b.w)) b.w = 0.5;
            if (std::isnan(b.h) || std::isinf(b.h)) b.h = 0.5;
            if (std::isnan(b.x) || std::isinf(b.x)) b.x = 0.5;
            if (std::isnan(b.y) || std::isinf(b.y)) b.y = 0.5;
            b.w = (b.w < 1) ? b.w : 1;
            b.h = (b.h < 1) ? b.h : 1;
            b.x = (b.x < 1) ? b.x : 1;
            b.y = (b.y < 1) ? b.y : 1;
            printf("%f %f %f %f\n", b.x, b.y, b.w, b.h);

            int left = (b.x - b.w / 2.)*show_img->cols;
            int right = (b.x + b.w / 2.)*show_img->cols;
            int top = (b.y - b.h / 2.)*show_img->rows;
            int bot = (b.y + b.h / 2.)*show_img->rows;

            if (left < 0) left = 0;
            if (right > show_img->cols - 1) right = show_img->cols - 1;
            if (top < 0) top = 0;
            if (bot > show_img->rows - 1) bot = show_img->rows - 1;

            int b_x_center = (left + right) / 2;
            int b_y_center = (top + bot) / 2;
            int b_width = right - left;
            int b_height = bot - top;
            sprintf(labelstr, "%d x %d - w: %d, h: %d", b_x_center, b_y_center, b_width, b_height);

            float const font_size = show_img->rows / 1000.F;
            cv::Size const text_size = cv::getTextSize(labelstr, cv::FONT_HERSHEY_COMPLEX_SMALL, font_size, 1, 0);
            cv::Point pt1, pt2, pt_text, pt_text_bg1, pt_text_bg2;
            pt1.x = left;
            pt1.y = top;
            pt2.x = right;
            pt2.y = bot;
            pt_text.x = left;
            pt_text.y = top - 4;// 12;
            pt_text_bg1.x = left;
            pt_text_bg1.y = top - (1 + 18 * font_size);
            pt_text_bg2.x = right;
            if ((right - left) < text_size.width) pt_text_bg2.x = left + text_size.width;
            pt_text_bg2.y = top;
            cv::Scalar color;
            color.val[0] = red * 256;
            color.val[1] = green * 256;
            color.val[2] = blue * 256;
            IplImage * ipl_im = mat_to_ipl(*show_img);

            // you should create directory: result_img
            static int copied_frame_id = -1;
            static IplImage* copy_img = NULL;
            if (copied_frame_id != frame_id) {
                copied_frame_id = frame_id;
                if(copy_img == NULL) copy_img = cvCreateImage(cvSize(b_width,b_height), ipl_im->depth, ipl_im->nChannels);
                cvCopy(show_img, copy_img, 0);
            }
            static int img_id = 0;
            img_id++;

            char image_name[1024];
            sprintf(image_name, "result_img/img_%d_%d_%d_%s.jpg", frame_id, img_id, class_id, names[class_id]);
            CvRect rect = cvRect(pt1.x, pt1.y, pt2.x - pt1.x, pt2.y - pt1.y);
            cvSetImageROI(copy_img, rect);
           // cvSaveImage(image_name, copy_img, 0);
            cvResetImageROI(copy_img);

            cv::rectangle(*show_img, pt1, pt2, color, width, 8, 0);
            if (ext_output)
                printf("\t(left_x: %4.0f   top_y: %4.0f   width: %4.0f   height: %4.0f)\n",
                (float)left, (float)top, b.w*show_img->cols, b.h*show_img->rows);
            else
                printf("\n");

            cv::rectangle(*show_img, pt_text_bg1, pt_text_bg2, color, width, 8, 0);
            cv::rectangle(*show_img, pt_text_bg1, pt_text_bg2, color, CV_FILLED, 8, 0);    // filled
            cv::Scalar black_color = CV_RGB(0,0,0);
            cv::putText(*show_img, labelstr, pt_text, cv::FONT_HERSHEY_COMPLEX_SMALL, font_size, black_color, 2*font_size, CV_AA);
            // cv::FONT_HERSHEY_COMPLEX_SMALL, cv::FONT_HERSHEY_SIMPLEX
        }
    }
    if (ext_output) {
        fflush(stdout);
    }
}

Буду признателен за любую помощь, спасибо

1 Ответ

1 голос
/ 03 мая 2019

Проблема заключалась в типе show_img, который является "cv :: Mat", однако функции cvCopy нужен тип "Iplimage". Итак, наконец, мы должны заменить старый код на этот:

                static int copied_frame_id = -1;
                static IplImage* copy_img = NULL;
                if (copied_frame_id != frame_id) {
                    copied_frame_id = frame_id;
                    if(copy_img == NULL) copy_img = cvCreateImage(cvSize(ipl_im->width, ipl_im->height), ipl_im->depth, ipl_im->nChannels);
                    cvCopy(ipl_im, copy_img, 0);

                }
                static int img_id = 0;
                img_id++;
                char image_name[1024];
                sprintf(image_name, "result_img/predicition_video", frame_id, img_id, class_id, names[class_id]);
                CvRect rect = cvRect(pt1.x, pt1.y, pt2.x - pt1.x, pt2.y - pt1.y);
                cvSetImageROI(copy_img, rect);
                cv::Mat imco = ipl_to_mat(copy_img);
                image imCopy = mat_to_image(imco);

               save_image(imCopy, image_name);

                cvResetImageROI(copy_img);
...