• 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)
    
    
  • 相关阅读:
    Redis分布式锁(中)
    H3C AC通过Web平台进行AC软件的升级?
    在uniapp中,如何去掉一些不想要的权限,
    解决tomcat时区错误问题
    按月分表数据分页查询
    用半天时间从零开始复习前端之html
    驱动开发DAY7
    诚迈科技发布OpenHarmony发行版鸿诚志远HongZOS
    软件工程毕业设计课题(80)微信小程序毕业设计PHP电影视频播放小程序系统设计与实现
    java 咖啡餐厅管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
  • 原文地址:https://blog.csdn.net/u011489887/article/details/139755146