Не могу понять, почему opencv.js cv.fitEllipse() запускает неперехваченное исключение с 1 изображением, но не с другим

#javascript #opencv

#javascript #opencv

Вопрос:

У меня есть эта функция, которая просто обрезает фон с изображения монеты и в основном работает.

но по какой-то причине «cv.fitEllipse» выдает мне неперехваченное исключение с этим изображением: плохое изображение

но отлично работает с этим изображением: хорошее изображение

Я в недоумении. есть идеи? Размер изображения, которое не работает, больше, но это единственное, что я могу понять.

есть идеи?

      Ellipse_img = function(el) {

            let src = cv.imread('imageChangeup');
            let gray = new cv.Mat();

            cv.cvtColor(src, gray, cv.COLOR_BGR2GRAY);

            let dst = new cv.Mat();

            cv.threshold(gray, dst, 0, 255, cv.THRESH_BINARY_INV   cv.THRESH_OTSU)[1];

            // apply morphology open and close
            let morph = new cv.Mat();
            kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, new cv.Size(5,5));
            cv.morphologyEx(dst, morph, cv.MORPH_OPEN, kernel);
            kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, new cv.Size(21,21));
            cv.morphologyEx(morph, morph, cv.MORPH_CLOSE, kernel);

            //find all the contours
            let contours = new cv.MatVector();
            let hierarchy = new cv.Mat();
            cv.findContours(morph, contours, hierarchy, cv.RETR_CCOMP, cv.CHAIN_APPROX_SIMPLE);

            //find largest contour
            let area_max =0;
            let i_max = 0;
            let cnt_max = 0;

            for (let i = 0; i < contours.size(); i  ) {
                let cnt = contours.get(i);
                let area = cv.contourArea(cnt, false);
                if(area >= area_max){
                    area_max = area;
                    i_max = i;
                    cnt_max = cnt;
                }
            }

            let rotatedRect = cv.fitEllipse(cnt_max);  //<<<<<<<<<<<<THE PROBLEM???

            let ellipseColor = new cv.Scalar(255, 255, 255, 255);
            let ellipseColor2 = new cv.Scalar(255, 255, 255, 255);

            cv.ellipse1(src, rotatedRect, ellipseColor, 3, cv.LINE_8);

            let mask = new cv.Mat.ones(src.size(), cv.CV_8UC3);
            cv.ellipse1(mask, rotatedRect, ellipseColor2, -1, cv.LINE_8);
            cv.cvtColor(mask, mask, cv.COLOR_BGR2GRAY);
            cv.bitwise_and(src, src, dst, mask);
            
            cv.imshow('imageChangeup', dst);

            src.delete();
            dst.delete();
            gray.delete();
            morph.delete();
            contours.delete();
            hierarchy.delete();

        };
  

вот высокий уровень cnt_max для хорошего и плохого — не должен находить круг, но почему?

 cnt_max:  data32S: Int32Array(2426)

cnt_max:  data32S: Int32Array(8)
  

Ответ №1:

Я недостаточно осведомлен, чтобы знать, почему … но.. это было связано с белым цветом вокруг объекта на «хорошем» изображении и используемым ПОРОГОМ.

Это сработало, если я изменил пороговые значения в зависимости от фона

 cv.threshold(gray, dst, 0, 255, cv.THRESH_BINARY_INV   cv.THRESH_OTSU)[1]; //for light backgrounds

cv.threshold(gray, dst, 0, 255, cv.THRESH_OTSU)[1]; //for dark backgrounds
  

итак, я перешел на adaptiveThreshold и, похоже, работает для всех сценариев

 cv.adaptiveThreshold(gray, dst, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY_INV,11,2)