基于Python检测图像中牙齿尺寸(长度、宽度)的技术求助
获取牙齿图片尺寸的解决方案
嘿,我看你尝试用Python代码获取牙齿图片的尺寸,还写了一段结合PIL和OpenCV的代码对吧?我帮你梳理下代码里的小问题,再针对不同需求给出更实用的实现方案。
先说说你原代码里的几个小问题
- 打开图片的方式有点多余:
Image.open(open('kr1.jpg'))直接用Image.open('kr1.jpg')就足够了,没必要嵌套open()函数 - 导入的库有重复:比如
import numpy和import numpy as np重复了,pylab和matplotlib.pyplot也可以按需整合,不用都导入 - 你用黑色范围提取形状,但牙齿通常是浅色的,这个颜色区间可能抓不到牙齿区域,得调整方向
接下来分两种常见需求给你优化后的代码:
需求1:获取图片本身的像素尺寸
如果只是想知道整张图片的宽高(单位像素),这一步超级简单,用PIL就能直接搞定:
from PIL import Image # 打开目标图片 img = Image.open('kr1.jpg') # 获取尺寸:返回的是(宽度, 高度)的元组 img_width, img_height = img.size print(f"图片整体尺寸:宽度 {img_width} 像素,高度 {img_height} 像素")
需求2:获取牙齿区域的像素尺寸
如果是想单独获取牙齿在图片中的大小,那就需要先提取牙齿的轮廓,再计算它的边界框大小。这里用OpenCV来实现更方便:
import cv2 import numpy as np # 读取图片(OpenCV默认以BGR格式读取) img = cv2.imread('kr1.jpg') # 转为灰度图,简化后续处理 gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化处理:根据你的图片调整阈值,这里假设牙齿是亮色,背景偏暗 # 如果你牙齿是深色,就把THRESH_BINARY_INV改成THRESH_BINARY _, binary_img = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY_INV) # 查找图片中的轮廓 contours, _ = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 筛选出最大的轮廓(默认最大的就是牙齿,要是有多个物体可以再加筛选条件) if contours: largest_contour = max(contours, key=cv2.contourArea) # 计算轮廓的边界框:x,y是左上角坐标,w是宽度,h是高度 x, y, tooth_width, tooth_height = cv2.boundingRect(largest_contour) print(f"牙齿的像素尺寸:宽度 {tooth_width} 像素,高度 {tooth_height} 像素") # 可选:画出边界框,直观验证结果 cv2.rectangle(img, (x, y), (x + tooth_width, y + tooth_height), (0, 255, 0), 2) cv2.imshow('Teeth Bounding Box', img) cv2.waitKey(0) cv2.destroyAllWindows() else: print("没检测到牙齿轮廓哦,试试调整二值化的阈值,或者检查图片是否清晰")
额外补充:获取牙齿的物理尺寸(比如毫米)
如果需要真实的物理尺寸,得在图片里放一个已知尺寸的参照物(比如一元硬币,直径约25mm):
- 先按照上面的方法获取参照物的像素尺寸(比如硬币像素直径是200)
- 计算像素密度:
mm_per_pixel = 25 / 200 = 0.125(每像素对应0.125毫米) - 用牙齿的像素尺寸乘以这个密度,就能得到物理尺寸:
tooth_real_width = tooth_width * mm_per_pixel
另外,你原代码里的颜色范围提取,要是想用的话,得把区间改成牙齿的颜色范围,比如浅色牙齿可以设:
lower = np.array([200, 200, 200]) upper = np.array([255, 255, 255])
内容的提问来源于stack exchange,提问作者Mishka
相关产品推荐
相关产品推荐

