我正在使用OpenCV4Android版本2.4.11,我正在检测相机检索到的帧中的任何矩形形状。如下面的image_1所示,我在检测到的物体周围绘制了一个黑色的轮廓,以及我想要做的事情 是,为了获得绘制轮廓的所有坐标,只能绘制为黑色的坐标。我尝试的是,如下面的 code_1 所示,我得到最大的轮廓和最大轮廓的索引并将它们保存在 “largestContour”和“largest_contour_index”分别为。然后,我使用
绘制轮廓Imgproc.drawContours(mMatInputFrame, contours, largest_contour_index, new Scalar(0, 0, 0), 2, 8, hierachy, 0, new Point());
然后我将最大轮廓的点传递给FindCorners类,因为我想找到以黑色绘制的轮廓的特定坐标,如下所示:
this.mFindCorners = new FindCorners(largestContour.toArray());
double[] cords = this.mFindCorners.getCords();
以下代码行:
double[] cords = this.mFindCorners.getCords();
应该给我更小的x坐标,最小的y坐标,最大的x坐标和最大的y坐标。但是当我在“this.mFindCorners.getCords();”得到的坐标周围绘制一个圆圈时,我有类似的东西 在下面的image_2中,这只是BoundingRect的角落。
实际上我不想要来自boundingRect的任何坐标我希望能够访问在balck中检测到的对象周围绘制的轮廓坐标
请告诉我如何获取轮廓的坐标?
code_1 :
if (contours.size() > 0) {
for (int i = 0; i < contours.size(); i++) {
contour2f = new MatOfPoint2f(contours.get(i).toArray());
approxDistance = Imgproc.arcLength(contour2f, true) * .01;//.02
approxCurve = new MatOfPoint2f();
Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true);
points = new MatOfPoint(approxCurve.toArray());
double area = Math.abs(Imgproc.contourArea(points, true));
if (points.total() >= 4 && area >= 40000 && area <= 200000) {
if (area > largest_area) {
largest_area = area;
largest_contour_index = i;
pointsOfLargestContour = points;
largestContour = contours.get(i);
}
}
}
if (largest_area > 0) {
Imgproc.drawContours(mMatInputFrame, contours, largest_contour_index, new Scalar(0, 0, 0), 2, 8, hierachy, 0, new Point());
this.mFindCorners = new FindCorners(largestContour.toArray());
double[] cords = this.mFindCorners.getCords();
Core.circle(mMatInputFrame, new Point(cords[0], cords[1]), 10, new Scalar(255, 0, 0));
Core.circle(mMatInputFrame, new Point(cords[2], cords[3]), 10, new Scalar(255, 255, 0));
}
FindCorners :
public class FindCorners {
private final static String TAG = FragOpenCVCam.class.getSimpleName();
private ArrayList<Double> mlistXCords = null;
private ArrayList<Double> mlistYCords = null;
private double mSmallestX;
private double mSmallestY;
private double mLargestX;
private double mLargestY;
private double[] mCords = null;
public FindCorners(Point[] points) {
this.mlistXCords = new ArrayList<>();
this.mlistYCords = new ArrayList<>();
this.mCords = new double[4];
Log.d(TAG, "points.length: " + points.length);
for (int i = 0; i < points.length; i++) {
this.mlistXCords.add(points[i].x);
this.mlistYCords.add(points[i].y);
}
//ascending
Collections.sort(this.mlistXCords);
Collections.sort(this.mlistYCords);
this.mSmallestX = this.mlistXCords.get(0);
this.mSmallestY = this.mlistYCords.get(0);
this.mLargestX = this.mlistXCords.get(this.mlistXCords.size() - 1);
this.mLargestY = this.mlistYCords.get(this.mlistYCords.size() - 1);
this.mCords[0] = this.mSmallestX;
this.mCords[1] = this.mSmallestY;
this.mCords[2] = this.mLargestX;
this.mCords[3] = this.mLargestY;
}
public double[] getCords() {
return this.mCords;
}
}
IMAGE_1 :
IMAGE_2 :
更新 我不想拥有边界矩形的坐标,我想要的是黑色轮廓的精确坐标。如图像3所示,我从我的代码得到的坐标是红色和黄色圆圈的位置..但我正在寻找访问黑线“轮廓”的坐标,所以我可以在其上绘制一些圆圈,如图所示IMAGE_3。绿色斑点只是为了向您展示我想要坐标的位置。
IMAGE_3 :
答案 0 :(得分:0)
您的问题是您已经分别对x和y进行了分类,很明显您的算法会找到红点和黄点。 我可以建议以下算法:
int min_x=INF, min_x_index, min_y=1000, min_y_index;
int max_x=-1, max_x_index, max_y=-1, max_y_index;
for (int i = 0; i < points.length; i++)
{
if(points[i].x < min_x) { min_x = points[i].x; min_x_index = i; }
if(points[i].x > max_x) { max_x = points[i].x; max_x_index = i; }
if(points[i].y < min_y) { min_y = points[i].y; min_y_index = i; }
if(points[i].y > max_y) { max_y = points[i].y; max_y_index = i; }
}
Point corner1(points[min_x_index]);
Point corner2(points[min_y_index]);
Point corner3(points[max_x_index]);
Point corner4(points[max_y_index]);