xiaohuangnlxx 2022-04-04 11:17 采纳率: 66.7%
浏览 132
已结题

图像转动角度识别到一半出现报错TypeError: object of type 'float' has no len()

使用orb进行关键点匹配的,图像处理一开始都没有问题,处理到一半出现

import cv2
import numpy
import os
from math import sqrt, pow, acos


def cv_show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(10000)
    cv2.destroyAllWindows()

def orb_features(img):
    orb = cv2.ORB_create(
        5000,  # 特征点数目
        1.2,  # 金字塔层级之间的缩放比例
        8,  # 金字塔图像层级系数
        31,  # 边缘阈值
        0,  # 原图在金字塔中的层数
        2,  # 生成描述子时需要用的像素点数目
        cv2.ORB_HARRIS_SCORE,  # 使用Harris方法评价特征点
        31,  # 生成描述子时关键点周围邻域的尺寸
        20  # 计算FAST角点时像素值差值的阈值
    )

    kp = orb.detect(img, None)

    kp, des = orb.compute(img, kp)

    return kp, des


if __name__ == '__main__':
    # f = open("output.txt")
    img_path = "D://python//txsc"
    for img in range(647):
        # print(f"{i}.jpg".rjust(10, "0"))
        img_name1 = f"{img}.jpg".rjust(10, "0")
        img_name2 = f"{img + 1}.jpg".rjust(10, "0")

        img_name1 = os.path.join(img_path, img_name1)
        img_name2 = os.path.join(img_path, img_name2)

        img1 = cv2.imread(img_name1)[350:750, 450:1450]
        img2 = cv2.imread(img_name2)[350:750, 450:1450]

        kp1, des1 = orb_features(img1)
        kp2, des2 = orb_features(img2)
        outimg1 = cv2.drawKeypoints(img1, keypoints=kp1, outImage=None)
        outimg2 = cv2.drawKeypoints(img2, keypoints=kp2, outImage=None)

        matcher = cv2.BFMatcher(cv2.NORM_HAMMING)  # 定义特征点匹配的类
        matches = matcher.match(des1, des2)  # 进行特征点匹配

        min_dist = 10000
        max_dist = 0
        # 提取最大距离和最小距离
        for i in range(len(matches)):
            dist = matches[i].distance
            if dist < min_dist:
                min_dist = dist
            if dist > max_dist:
                max_dist = dist

        """
        //将汉明距离较大的匹配点对剔除,并缩小特征点选取范围
        vector<DMatch> good_matches;//用于储存剔除完的结果
        int matchidx1, matchidx2;//用于储存匹配点在查询子和描述子中的序号
        float matchx1, matchy1;//用于储存匹配点在查询子中的坐标
        float matchx2, matchy2;//用于储存匹配点在描述子中的坐标
        """
        good_matches = []
        for i in range(len(matches)):
            matchidx1 = matches[i].queryIdx
            matchidx2 = matches[i].trainIdx
            matchx1, matchy1 = kp1[matchidx1].pt
            matchx2, matchy2 = kp2[matchidx2].pt

            if (matches[i].distance <= max(3 * min_dist, 40.0) and
                    (sqrt(pow((matchx1 - 278), 2) + pow((matchy1 - 269), 2)) > 158) and
                    (sqrt(pow((matchx1 - 278), 2) + pow((matchy1 - 269), 2)) < 250) and
                    (sqrt(pow((matchx2 - 278), 2) + pow((matchy2 - 269), 2)) > 158) and
                    (sqrt(pow((matchx2 - 278), 2) + pow((matchy2 - 269), 2)) < 250) and
                    (matchy1 < 0.66 * matchx1 + 83.5) and
                    (matchy1 < -1.64 * matchx1 + 725) and
                    (matchy2 < 0.66 * matchx2 + 83.5) and
                    (matchy2 < -1.64 * matchx2 + 725)):
                good_matches.append(matches[i])



        nums1 = []
        # 计算所有匹配点转过的角度
        for i in range(len(good_matches)):
            index1 = good_matches[i].queryIdx
            index2 = good_matches[i].trainIdx
            ax, ay = kp1[index1].pt
            bx, by = kp2[index2].pt
            OA = sqrt(pow(ax - 278, 2) + pow(ay - 269, 2))
            OB = sqrt(pow(bx - 278, 2) + pow(by - 269, 2))
            AB = sqrt(pow(ax - bx, 2) + pow(ay - by, 2))
            costheta = (pow(OA, 2) + pow(OB, 2) - pow(AB, 2)) / (2 * OA * OB)
            # print(costheta)
            theta = acos(round(costheta, 2)) / 3.1415926 * 180
            nums1.append(theta)

        # 创建用于归类角度的矩阵numinrange和计数的矩阵count
        """
        vector<vector<float>> numinrange(31, vector<float>(1, 0)); //创建30行,1列,值为0的二维数组
        vector<float> count(31, 0);//计数用的数组,长度与划分的范围数量相等
        """
        HANG = 30
        numinrange = [[0]] * 30
        count = []

        for i in range(len(nums1)):
            if nums1[i] == 0:
                numinrange.append(nums1[i])
                count.append(i + 1)

        # 将num1中的角度theta归到二维数组中相应范围内,每归入一个相应计数加一
        for i in range(31):
            for j in range(len(nums1)):
                if (nums1[j] > 3 * i - 3) and (nums1[j] <= 3 * i):
                    numinrange[i].append(nums1[j])
                    count[i] += 1

        # //查找0以外计数最大的行数
        max1 = 0
        maxnum = 0
        for i in range(2, len(count)):
            if count[i] >= max1:
                max1 = count[i]
                maxnum = i

        # 不动的点需多于其余点三倍以上才能被计算
        if count[0] > 30 * (len(good_matches) - count[0] - count[1]) + 6:
            max1 = count[0]
            maxnum = 0
        elif count[1] > 30 * (len(good_matches) - count[0] - count[1]) + 10:
            max1 = count[1]
            maxnum = 1

        """
        //取平均值计算转角
        float sum, ave, rec;
        """
        sum = 0
        ave = 0

        for i in range(1, len(numinrange[maxnum])):
            rec = numinrange[maxnum][i]
            sum += rec

        ave = sum / count[maxnum]

        print(f"图片{img}, 转过角度 {ave}")

        with open(f"ave/{img}.txt", "w", encoding="utf-8") as f:
            f.write(f"{ave}")

运行结果及报错内容

报错内容:

img


关键点匹配存在问题,能够匹配上的点太少:

img

我的解答思路和尝试过的方法

现阶段orb关键点大部分匹配不上,有可能是主要原因,想问问应该要怎么调整比较好

我想要达到的结果

提高关键点的匹配数量

  • 写回答

1条回答 默认 最新

  • 赵4老师 2022-04-06 13:47
    关注
    if type(numinrange[maxnum])<>'float':
         for i in range(1, len(numinrange[maxnum])):
                rec = numinrange[maxnum][i]
                sum += rec
    else:
        print("type(numinrange[maxnum])=='float'")
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月7日
  • 已采纳回答 4月7日
  • 修改了问题 4月4日
  • 创建了问题 4月4日

悬赏问题

  • ¥15 matlab有关常微分方程的问题求解决
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable