Search code examples
c++opencvvideocropdarknet

my video flow has been crashed while running darknet.exe for detection object


I'm working on a deap learning project to detect license plate from a video flow , so I'm using darknet (yolov3) , opencv 4.1.0 and OCR

Right now the project is able to detect license plate from image and crop the license then send it to an OCR program to recognize the text

But when the input is a video or when i open the webcam camera ,I got an error when first it detect the license plate .

this is the error I've got :

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

This is the code of matrix_c.cpp that cause an error

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");
}

This is the code of the function draw_detections_cv_v3 to Draw detection , and I realised that it blocks every time it reach this code :

 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);
    }
}

I'd appreciate any help ,thank you


Solution

  • The problem was the type of the show_img which is "cv::Mat" , however the cvCopy function need a "Iplimage" type So finally we should replace the old code with that one:

                    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);