• PCA 在图像分析上的应用


    同一物体旋转角度求取

    直接上代码:

    import cv2, os
    import numpy as np
    import time
    
    def perform_pca(image, num_components):
        # 将图像转换为浮点型
        img_float = np.float32(image)
    
        img_flatten = img_float.reshape(-1, 2)
        
        # 计算均值和协方差矩阵
        mean, eigenvectors = cv2.PCACompute(img_flatten, mean=None, maxComponents=num_components)
        
        return mean, eigenvectors
    
    def rotate_coords(coords, theta):
        """
        绕原点旋转坐标点集。
    
        参数:
        coords: 坐标点集,每个元素是一个(x, y)的元组。
        theta: 旋转角度,以弧度为单位。
    
        返回:
        旋转后的坐标点集。
        """
        # 定义旋转矩阵
        rotation_matrix = np.array([[np.cos(theta), -np.sin(theta)],
                                    [np.sin(theta), np.cos(theta)]])
        
        # 将坐标点集转换为NumPy数组以便进行矩阵运算
        coords_array = np.array(coords)
        
        # 应用旋转矩阵
        rotated_coords = np.dot(coords_array, rotation_matrix)
        
        return rotated_coords
    
    def judge_direction1(mean, vector, center_x, center_y):
        v = np.array([center_x - mean[0][0], center_y - mean[0][1]])
        if np.dot(v, vector) < 0:
            vector = -vector
        return vector
    
    def judge_direction2(mean, vector, image, img_path):
        edge_image = cv2.Canny(image, 50, 200)
        file_name = img_path.split("/")[-1]
        save_path = "/home/xxx/下载/mask/result/"
    
        x_angle = vector_angle(vector,np.array([1, 0]))
        edge_non_zero_coords = cv2.findNonZero(edge_image)
        edge_non_zero_coords = edge_non_zero_coords - mean[0]
        edge_non_zero_coords = rotate_coords(edge_non_zero_coords, np.radians(x_angle))
    
        min_x, min_y = np.min(edge_non_zero_coords, axis=0)[0]
        max_x, max_y = np.max(edge_non_zero_coords, axis=0)[0]
    
        new_image = np.zeros((int(max_y-min_y)+1, int(max_x - min_x)+1), np.uint8)
        for coord in edge_non_zero_coords:
            x, y = coord[0]
            new_image[int(y - min_y), int(x - min_x)] = 255
        # cv2.imwrite(save_path + file_name, new_image)
    
        if max_x - min_x > max_y - min_y:
            if abs(max_x) > abs(min_x):
                vector = -vector
        else:
            if abs(max_y) > abs(min_y):
                vector = -vector
        return vector
    
    def get_vector(img_path):
        image = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
    
        h, w = image.shape
        center_x = int(w / 2)
        center_y = int(h / 2)
        non_zero_coords = cv2.findNonZero(image)
    
        # 执行PCA
        num_components = 2
        mean, eigenvectors = perform_pca(non_zero_coords, num_components)
        vector = eigenvectors[0]
    
        vector = judge_direction2(mean, vector, image, img_path)
        return vector
    
    def vector_angle(v1, v2):
        # 计算点积
        dot_product = np.dot(v1, v2)
        
        # 计算向量的模
        norm_v1 = np.linalg.norm(v1)
        norm_v2 = np.linalg.norm(v2)
        
        # 计算余弦值
        cos_theta = dot_product / (norm_v1 * norm_v2)
        
        # 计算弧度制的夹角
        theta_rad = np.arccos(np.clip(cos_theta, -1.0, 1.0))
        
        # 将弧度制转换为角度制
        theta_deg = np.degrees(theta_rad)
        
        # 确定角度的方向性
        cross_product = np.cross(v1, v2)
        if cross_product < 0:
            theta_deg = 360 - theta_deg
        
        return 360 - theta_deg
    
    def get_angle(img_path1, img_path2):
        vector1 = get_vector(img_path1)
        vector2 = get_vector(img_path2)
        
        angle = vector_angle(vector1, vector2)
        print(vector1, vector2, angle)
        return angle
    
    if __name__ == "__main__":
        img_path1 = "/home/xxx/下载/mask/mask3/0.jpg"
        img_path2 = "/home/xxx/下载/mask/mask3/32.jpg"
        get_angle(img_path1, img_path2)
    
    
  • 相关阅读:
    踏进字节的那一瞬间,我泪目了,这437天的外包经历值了....
    基于SpringBoot的航班进出港管理系统
    echarts案例之日历
    怎么将PDF文件转换成图片呢?
    ubuntu 设置和取消代理
    ITIL4背景下,ITSM产品应具备哪些特点?
    vueX的使用
    PIE:1979-2018年中国气温数据产品(空间分辨率为0.1º)
    viewport视口的概念
    3.cuBLAS开发指南中文版--cuBLAS数据类型引用
  • 原文地址:https://blog.csdn.net/u011489887/article/details/139755146