白日屠烈 2025-09-29 16:50 采纳率: 66.7%
浏览 11
已结题

我如何用Python编程获得图片中的效果

img


我想用Python分离舌体,舌苔和舌质,获得如图效果,该怎么办

  • 写回答

5条回答 默认 最新

  • 宝码香车 优质创作者: JavaScript技术领域 2025-09-29 17:21
    关注

    让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。

    如果答案让您满意,请采纳、点赞、关注,非常感谢!
    .
    每日一句正能量,让它带给您好心情:别让过去的错误,惩罚现在的自己。
    .

    Python实现舌体、舌苔与舌质分离的方法

    根据您的需求,要实现舌体、舌苔和舌质的分离,主要涉及图像处理和计算机视觉技术。以下是完整的解决方案:

    核心思路

    1. 舌体分割 - 从背景中分离出舌头区域
    2. 舌苔舌质分离 - 基于颜色特征区分舌苔和舌质
    3. 特征提取 - 计算颜色统计特征

    完整代码实现

    import cv2
    import numpy as np
    from sklearn.cluster import KMeans
    import matplotlib.pyplot as plt
    
    
    class TongueAnalyzer:
        def __init__(self):
            self.tongue_mask = None
            self.coating_mask = None
            self.body_mask = None
            
        def preprocess_image(self, image_path):
            """图像预处理"""
            image = cv2.imread(image_path)
            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
            # 图像增强
            hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
            hsv[:,:,2] = cv2.equalizeHist(hsv[:,:,2])
            enhanced = cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)
            return enhanced
        
        def segment_tongue(self, image):
            """舌体分割"""
            # 转换为HSV颜色空间
            hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
            
            # 定义舌头的颜色范围(红色调)
            lower_red1 = np.array([0, 50, 50])
            upper_red1 = np.array([10, 255, 255])
            lower_red2 = np.array([170, 50, 50])
            upper_red2 = np.array([180, 255, 255])
            
            mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
            mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
            tongue_mask = mask1 + mask2
            
            # 形态学操作去除噪声
            kernel = np.ones((5,5), np.uint8)
            tongue_mask = cv2.morphologyEx(tongue_mask, cv2.MORPH_CLOSE, kernel)
            tongue_mask = cv2.morphologyEx(tongue_mask, cv2.MORPH_OPEN, kernel)
            
            # 找到最大连通区域
            contours, _ = cv2.findContours(tongue_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            if contours:
                largest_contour = max(contours, key=cv2.contourArea)
                tongue_mask = np.zeros_like(tongue_mask)
                cv2.fillPoly(tongue_mask, [largest_contour], 255)
            
            self.tongue_mask = tongue_mask
            return tongue_mask
        
        def separate_coating_body(self, image, tongue_mask):
            """分离舌苔和舌质"""
            # 提取舌体区域
            tongue_region = cv2.bitwise_and(image, image, mask=tongue_mask)
            
            # 转换为LAB颜色空间,更好的颜色分离
            lab = cv2.cvtColor(tongue_region, cv2.COLOR_RGB2LAB)
            
            # 使用K-means聚类分离舌苔和舌质
            pixels = lab.reshape(-1, 3)
            pixels = pixels[np.where(tongue_mask.flatten() == 255)[0]]
            
            kmeans = KMeans(n_clusters=2, random_state=42)
            labels = kmeans.fit_predict(pixels)
            
            # 根据亮度区分舌苔和舌质
            cluster_centers = kmeans.cluster_centers_
            brightness = cluster_centers[:, 0]  # L通道表示亮度
            
            # 较亮的为舌苔,较暗的为舌质
            coating_cluster = np.argmax(brightness)
            body_cluster = np.argmin(brightness)
            
            # 创建掩码
            coating_mask_full = np.zeros_like(tongue_mask)
            body_mask_full = np.zeros_like(tongue_mask)
            
            tongue_indices = np.where(tongue_mask.flatten() == 255)[0]
            coating_mask_full.flat[tongue_indices[labels == coating_cluster]] = 255
            body_mask_full.flat[tongue_indices[labels == body_cluster]] = 255
            
            self.coating_mask = coating_mask_full
            self.body_mask = body_mask_full
            
            return coating_mask_full, body_mask_full
        
        def calculate_color_features(self, image, mask):
            """计算颜色特征"""
            region = cv2.bitwise_and(image, image, mask=mask)
            pixels = region.reshape(-1, 3)
            pixels = pixels[np.where(mask.flatten() == 255)[0]]
            
            if len(pixels) == 0:
                return {'red_mean': 0, 'red_std': 0, 'green_mean': 0, 'green_std': 0, 
                       'blue_mean': 0, 'blue_std': 0, 'yellow_index': 0, 'purple_index': 0}
            
            # 基本颜色统计
            red_mean = np.mean(pixels[:, 0])
            green_mean = np.mean(pixels[:, 1])
            blue_mean = np.mean(pixels[:, 2])
            
            red_std = np.std(pixels[:, 0])
            green_std = np.std(pixels[:, 1])
            blue_std = np.std(pixels[:, 2])
            
            # 黄度指数 (基于RGB)
            yellow_index = (red_mean + green_mean) / 2 - blue_mean
            
            # 紫度指数
            purple_index = (red_mean + blue_mean) / 2 - green_mean
            
            return {
                'red_mean': red_mean,
                'red_std': red_std,
                'green_mean': green_mean,
                'green_std': green_std,
                'blue_mean': blue_mean,
                'blue_std': blue_std,
                'yellow_index': yellow_index,
                'purple_index': purple_index
            }
        
        def analyze_tongue(self, image_path):
            """完整的舌象分析流程"""
            # 1. 预处理
            image = self.preprocess_image(image_path)
            
            # 2. 舌体分割
            tongue_mask = self.segment_tongue(image)
            
            # 3. 舌苔舌质分离
            coating_mask, body_mask = self.separate_coating_body(image, tongue_mask)
            
            # 4. 特征计算
            coating_features = self.calculate_color_features(image, coating_mask)
            body_features = self.calculate_color_features(image, body_mask)
            
            # 5. 可视化结果
            self.visualize_results(image, tongue_mask, coating_mask, body_mask, 
                                  coating_features, body_features)
            
            return {
                'coating_features': coating_features,
                'body_features': body_features
            }
        
        def visualize_results(self, image, tongue_mask, coating_mask, body_mask, 
                             coating_features, body_features):
            """可视化分析结果"""
            fig, axes = plt.subplots(2, 3, figsize=(15, 10))
            
            # 原图
            axes[0,0].imshow(image)
            axes[0,0].set_title('原图')
            axes[0,0].axis('off')
            
            # 舌体分割
            tongue_vis = image.copy()
            tongue_vis[tongue_mask == 0] = [0, 0, 0]
            axes[0,1].imshow(tongue_vis)
            axes[0,1].set_title('舌体分割')
            axes[0,1].axis('off')
            
            # 舌苔
            coating_vis = image.copy()
            coating_vis[coating_mask == 0] = [0, 0, 0]
            axes[0,2].imshow(coating_vis)
            axes[0,2].set_title('舌苔区域')
            axes[0,2].axis('off')
            
            # 舌质
            body_vis = image.copy()
            body_vis[body_mask == 0] = [0, 0, 0]
            axes[1,0].imshow(body_vis)
            axes[1,0].set_title('舌质区域')
            axes[1,0].axis('off')
            
            # 合并显示
            combined = np.zeros_like(image)
            combined[coating_mask == 255] = [255, 255, 0]  # 舌苔用黄色
            combined[body_mask == 255] = [255, 0, 0]       # 舌质用红色
            axes[1,1].imshow(combined)
            axes[1,1].set_title('分离结果')
            axes[1,1].axis('off')
            
            # 特征显示
            axes[1,2].axis('off')
            feature_text = f"""舌质特征:
    红度: {body_features['red_mean']:.1f}
    紫度: {body_features['purple_index']:.1f}
    
    
    舌苔特征:
    黄度: {coating_features['yellow_index']:.1f}
    厚度指标: {coating_features['red_std']:.1f}"""
            axes[1,2].text(0.1, 0.9, feature_text, transform=axes[1,2].transAxes, 
                          fontsize=12, verticalalignment='top')
            
            plt.tight_layout()
            plt.show()
    
    
    # 使用示例
    if __name__ == "__main__":
        analyzer = TongueAnalyzer()
        
        # 分析舌象图片
        result = analyzer.analyze_tongue('tongue_image.jpg')
        
        print("舌质颜色特征:")
        print(f"红度平均值: {result['body_features']['red_mean']:.2f}")
        print(f"紫度平均值: {result['body_features']['purple_index']:.2f}")
        
        print("\n舌苔颜色特征:")
        print(f"黄度平均值: {result['coating_features']['yellow_index']:.2f}")
    

    安装依赖

    pip install opencv-python numpy scikit-learn matplotlib
    

    关键步骤说明

    1. 图像预处理:增强对比度,改善分割效果
    2. 舌体分割:基于HSV颜色空间识别舌头区域
    3. 舌苔舌质分离:使用K-means聚类根据颜色特征分离
    4. 特征提取:计算红度、紫度、黄度等颜色特征

    调优建议

    • 根据具体图片调整颜色阈值范围
    • 可以尝试不同的聚类数量
    • 考虑使用深度学习模型提高分割精度
    • 结合形态学特征分析舌形、齿痕等

    这个方案提供了完整的舌象分析流程,您可以根据实际需求调整参数和算法。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

问题事件

  • 系统已结题 10月7日
  • 已采纳回答 9月29日
  • 创建了问题 9月29日