Я использую OpenCV4Android версии 2.4.11, и я пытаюсь обнаружить прямоугольники в кадрах, извлеченных из камеры. Я упомянул некоторые вопросы на этом веб-сайте, и они были настолько полезными. но проблема, с которой я сейчас сталкиваюсь, - , когда я пытаюсь обнаружить объект со светлым цветом в середине, как показано на исходном изображении ниже алгоритма обнаружения, в этом случае не обнаруживает объект целиком, а обнаруживает темные части как показано на рисунке в разделе «обработан» ниже.Как определить весь прямоугольник в кадре
приведенный ниже код указывает шаги, которые я выполнил, и пороговые значения, которые я использовал для обнаружения объектов в кадрах.
пожалуйста, дайте мне знать, почему объект в целом не получает обнаружить и то, что я могу сделать, чтобы обнаружить весь объект не только его части
код:
//step 1
this.mMatGray = new Mat();
Imgproc.cvtColor(this.mMatInputFrame, this.mMatGray, Imgproc.COLOR_BGR2GRAY);
//step 2
this.mMatEdges = new Mat();
Imgproc.blur(this.mMatGray, this.mMatEdges, new Size(7, 7));//7,7
//step 3
Imgproc.Canny(this.mMatEdges, this.mMatEdges, 128, 128*2, 5, true);//..,..,2,900,7,true
//step 4
dilated = new Mat();
Mat dilateElement = Imgproc.getStructuringElement(Imgproc.MORPH_DILATE, new Size(3, 3));
Imgproc.dilate(mMatEdges, dilated, dilateElement);
ArrayList<MatOfPoint> contours = new ArrayList<>();
hierachy = new Mat();
Imgproc.findContours(dilated, contours, hierachy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
MatOfPoint2f approxCurve = new MatOfPoint2f();
if (contours.size() > 0) {
for (int i = 0; i < contours.size(); i++) {
MatOfPoint2f contour2f = new MatOfPoint2f(contours.get(i).toArray());
double approxDistance = Imgproc.arcLength(contour2f, true) * .02;//.02
Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true);
MatOfPoint points = new MatOfPoint(approxCurve.toArray());
if (points.total() >= 4 && Imgproc.isContourConvex(points) && Math.abs(Imgproc.contourArea(points)) >= 40000 && Math.abs(Imgproc.contourArea(points)) <= 150000) {
Rect boundingRect = Imgproc.boundingRect(points);
RotatedRect minAreaRect = Imgproc.minAreaRect(contour2f);
Point[] rectPoints = new Point[4];
minAreaRect.points(rectPoints);
Rect minAreaAsRect = minAreaRect.boundingRect();
//to draw the minAreaRect
for(int j = 0; j < 4; j++) {
Core.line(mMatInputFrame, rectPoints[j], rectPoints[(j+1)%4], new Scalar(255,0,0));
}
Core.putText(mMatInputFrame, "MinAreaRect", new Point(10, 30), 1,1 , new Scalar(255,0,0),2);
Core.putText(mMatInputFrame, "Width: " + minAreaAsRect.width , new Point(minAreaAsRect.tl().x, minAreaAsRect.tl().y-100), 1,1 , new Scalar(255,0,0),2);
Core.putText(mMatInputFrame, "Height: " + minAreaAsRect.height, new Point(minAreaAsRect.tl().x, minAreaAsRect.tl().y-80), 1,1 , new Scalar(255,0,0),2);
Core.putText(mMatInputFrame, "Area: " + minAreaAsRect.area(), new Point(minAreaAsRect.tl().x, minAreaAsRect.tl().y-60), 1,1 , new Scalar(255,0,0),2);
//drawing the contour
Imgproc.drawContours(mMatInputFrame, contours, i, new Scalar(0,0,0),2);
//drawing the boundingRect
Core.rectangle(mMatInputFrame, boundingRect.tl(), boundingRect.br(), new Scalar(0, 255, 0), 1, 1, 0);
Core.putText(mMatInputFrame, "BoundingRect", new Point(10, 60), 1,1 , new Scalar(0,255,0),2);
Core.putText(mMatInputFrame, "Width: " + boundingRect.width , new Point(boundingRect.br().x-100, boundingRect.tl().y-100), 1,1 , new Scalar(0,255,0),2);
Core.putText(mMatInputFrame, "Height: " + boundingRect.height, new Point(boundingRect.br().x-100, boundingRect.tl().y-80), 1,1 , new Scalar(0,255,0),2);
Core.putText(mMatInputFrame, "Area: " + Imgproc.contourArea(points), new Point(boundingRect.br().x-100, boundingRect.tl().y-60), 1,1 , new Scalar(0,255,0),2);
}
}
}
оригинал изображение:
обработанное изображение:
спасибо .. скажите, пожалуйста, пожалуйста, почему вы использовали «erode then dailate then erode» ?? – user2121
Чтобы построить связь между недельными отключенными краями ... –
do u думаю, если бы я использовал детектор края Canny, я бы не получил одинаковые результаты? – user2121