gzpcgreen 2021-11-14 23:22 采纳率: 40%
浏览 141
已结题

有谁可以帮吧opencv java代码转为python?

原网址是java,本人不会java,想转成pthon实现,有谁可以帮忙转换一下
https://www.cnblogs.com/josephkim/p/8319069.html


// MeanShift滤波,降噪(速度太慢!)
//Imgproc.pyrMeanShiftFiltering(img, img, 30, 10);

// 彩色转灰度
Imgproc.cvtColor(img, img, Imgproc.COLOR_BGR2GRAY);

// 高斯滤波,降噪
Imgproc.GaussianBlur(img, img, new Size(3,3), 2, 2);

// Canny边缘检测
Imgproc.Canny(img, img, 20, 60, 3, false);

// 膨胀,连接边缘
Imgproc.dilate(img, img, new Mat(), new Point(-1,-1), 3, 1, new Scalar(1));

List<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(img, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

// 根据三个点计算中间那个点的夹角   pt1 pt0 pt2
private static double getAngle(Point pt1, Point pt2, Point pt0)
{
    double dx1 = pt1.x - pt0.x;
    double dy1 = pt1.y - pt0.y;
    double dx2 = pt2.x - pt0.x;
    double dy2 = pt2.y - pt0.y;
    return (dx1*dx2 + dy1*dy2)/Math.sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}



// 找出轮廓对应凸包的四边形拟合
List<MatOfPoint> squares = new ArrayList<>();
List<MatOfPoint> hulls = new ArrayList<>();
MatOfInt hull = new MatOfInt();
MatOfPoint2f approx = new MatOfPoint2f();
approx.convertTo(approx, CvType.CV_32F);

for (MatOfPoint contour: contours) {
    // 边框的凸包
    Imgproc.convexHull(contour, hull);

    // 用凸包计算出新的轮廓点
    Point[] contourPoints = contour.toArray();
    int[] indices = hull.toArray();
    List<Point> newPoints = new ArrayList<>();
    for (int index : indices) {
        newPoints.add(contourPoints[index]);
    }
    MatOfPoint2f contourHull = new MatOfPoint2f();
    contourHull.fromList(newPoints);

    // 多边形拟合凸包边框(此时的拟合的精度较低)
    Imgproc.approxPolyDP(contourHull, approx, Imgproc.arcLength(contourHull, true)*0.02, true);

    // 筛选出面积大于某一阈值的,且四边形的各个角度都接近直角的凸四边形
    MatOfPoint approxf1 = new MatOfPoint();
    approx.convertTo(approxf1, CvType.CV_32S);
    if (approx.rows() == 4 && Math.abs(Imgproc.contourArea(approx)) > 40000 &&
            Imgproc.isContourConvex(approxf1)) {
        double maxCosine = 0;
        for (int j = 2; j < 5; j++) {
            double cosine = Math.abs(getAngle(approxf1.toArray()[j%4], approxf1.toArray()[j-2], approxf1.toArray()[j-1]));
            maxCosine = Math.max(maxCosine, cosine);
        }
        // 角度大概72度
        if (maxCosine < 0.3) {
            MatOfPoint tmp = new MatOfPoint();
            contourHull.convertTo(tmp, CvType.CV_32S);
            squares.add(approxf1);
            hulls.add(tmp);
        }
    }
}

// 找到最大的正方形轮廓
private static int findLargestSquare(List<MatOfPoint> squares) {
    if (squares.size() == 0)
        return -1;
    int max_width = 0;
    int max_height = 0;
    int max_square_idx = 0;
    int currentIndex = 0;
    for (MatOfPoint square : squares) {
        Rect rectangle = Imgproc.boundingRect(square);
        if (rectangle.width >= max_width && rectangle.height >= max_height) {
            max_width = rectangle.width;
            max_height = rectangle.height;
            max_square_idx = currentIndex;
        }
        currentIndex++;
    }
    return max_square_idx;
}



// 找出外接矩形最大的四边形
int index = findLargestSquare(squares);
MatOfPoint largest_square = squares.get(index);
if (largest_square.rows() == 0 || largest_square.cols() == 0)
    return result;

/ 找到这个最大的四边形对应的凸边框,再次进行多边形拟合,此次精度较高,拟合的结果可能是大于4条边的多边形
MatOfPoint contourHull = hulls.get(index);
MatOfPoint2f tmp = new MatOfPoint2f();
contourHull.convertTo(tmp, CvType.CV_32F);
Imgproc.approxPolyDP(tmp, approx, 3, true);
List<Point> newPointList = new ArrayList<>();
double maxL = Imgproc.arcLength(approx, true) * 0.02;

// 点到点的距离
private static double getSpacePointToPoint(Point p1, Point p2) {
    double a = p1.x - p2.x;
    double b = p1.y - p2.y;
    return Math.sqrt(a * a + b * b);
}

// 两直线的交点
private static Point computeIntersect(double[] a, double[] b) {
    if (a.length != 4 || b.length != 4)
        throw new ClassFormatError();
    double x1 = a[0], y1 = a[1], x2 = a[2], y2 = a[3], x3 = b[0], y3 = b[1], x4 = b[2], y4 = b[3];
    double d = ((x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4));
    if (d != 0) {
        Point pt = new Point();
        pt.x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;
        pt.y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;
        return pt;
    }
    else
        return new Point(-1, -1);
}



// 找到高精度拟合时得到的顶点中 距离小于低精度拟合得到的四个顶点maxL的顶点,排除部分顶点的干扰
for (Point p : approx.toArray()) {
    if (!(getSpacePointToPoint(p, largest_square.toList().get(0)) > maxL &&
            getSpacePointToPoint(p, largest_square.toList().get(1)) > maxL &&
            getSpacePointToPoint(p, largest_square.toList().get(2)) > maxL &&
            getSpacePointToPoint(p, largest_square.toList().get(3)) > maxL)) {
        newPointList.add(p);
    }
}

// 找到剩余顶点连线中,边长大于 2 * maxL的四条边作为四边形物体的四条边
List<double[]> lines = new ArrayList<>();
for (int i = 0; i < newPointList.size(); i++) {
    Point p1 = newPointList.get(i);
    Point p2 = newPointList.get((i+1) % newPointList.size());
    if (getSpacePointToPoint(p1, p2) > 2 * maxL) {
        lines.add(new double[]{p1.x, p1.y, p2.x, p2.y});
    }
}

// 计算出这四条边中 相邻两条边的交点,即物体的四个顶点
List<Point> corners = new ArrayList<>();
for (int i = 0; i < lines.size(); i++) {
    Point corner = computeIntersect(lines.get(i),lines.get((i+1) % lines.size()));
    corners.add(corner);
}
  • 写回答

2条回答 默认 最新

报告相同问题?

问题事件

  • 系统已结题 11月22日
  • 赞助了问题酬金 11月14日
  • 修改了问题 11月14日
  • 创建了问题 11月14日

悬赏问题

  • ¥60 全一数分解素因子和素数循环节位数
  • ¥15 ffmpeg如何安装到虚拟环境
  • ¥188 寻找能做王者评分提取的
  • ¥15 matlab用simulink求解一个二阶微分方程,要求截图
  • ¥30 乘子法解约束最优化问题的matlab代码文件,最好有matlab代码文件
  • ¥15 写论文,需要数据支撑
  • ¥15 identifier of an instance of 类 was altered from xx to xx错误
  • ¥100 反编译微信小游戏求指导
  • ¥15 docker模式webrtc-streamer 无法播放公网rtsp
  • ¥15 学不会递归,理解不了汉诺塔参数变化