一张图片当中,车辆的长度是11米,导弹的长度是7.7米,请按照第一张图的比例,计算第二张图上YJ-1...
创建于:2025年8月17日
使用 GPT-5 Thinking 回答 Chat01
创建于:2025年8月17日
使用 GPT-5 Thinking 回答 Chat01
pythonpaths = ["/mnt/data/E1908207394C3B69CDB2F77AC24D6A4A.jpg", "/mnt/data/CAECFACCBB7BC06959E0F905E0A18223.jpg", "/mnt/data/0FBCF1E0D53C7EFD49CD5D4EA8F26896.jpg"] for p in paths: im = Image.open(p) print(p, im.size)
pythonimport numpy as np, cv2 img2 = cv2.imread(paths[1])[:, :, ::-1] # to RGB hsv = cv2.cvtColor(img2, cv2.COLOR_RGB2HSV) # yellow range lower = np.array([15, 60, 100]) upper = np.array([45, 255, 255]) mask = cv2.inRange(hsv, lower, upper) # morphological open close kernel = np.ones((5,5), np.uint8) mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=1) mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=2) # find largest contour width contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) len(contours), sum(cv2.contourArea(c) for c in contours) (44, 53798.0)
python# get largest contours contours_sorted = sorted(contours, key=lambda c: cv2.contourArea(c), reverse=True) areas=[cv2.contourArea(c) for c in contours_sorted[:5]] areas [18916.5, 11098.5, 8457.5, 6576.0, 2901.5]
python# bounding box of largest contour c = contours_sorted[0] x,y,w,h = cv2.boundingRect(c) (x,y,w,h) (289, 118, 419, 188)
pythonimport matplotlib.pyplot as plt plt.imshow(img2) rect = plt.Rectangle((x,y), w,h, fill=False, linewidth=2) plt.gca().add_patch(rect) plt.axis('off') (-0.5, 809.5, 665.5, -0.5)
pythonimg2 = cv2.imread(paths[1])[:,:,::-1] hsv = cv2.cvtColor(img2, cv2.COLOR_RGB2HSV) # brown/orange range - guess lower_br = np.array([5, 50, 50]) upper_br = np.array([25, 255, 200]) mask_br = cv2.inRange(hsv, lower_br, upper_br) kernel = np.ones((5,5), np.uint8) mask_br = cv2.morphologyEx(mask_br, cv2.MORPH_OPEN, kernel, iterations=1) mask_br = cv2.morphologyEx(mask_br, cv2.MORPH_CLOSE, kernel, iterations=2) conts,_ = cv2.findContours(mask_br, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) conts_sorted = sorted(conts, key=lambda c: cv2.contourArea(c), reverse=True) areas=[cv2.contourArea(c) for c in conts_sorted[:5]] areas[:5] [327866.0, 8912.5, 1050.0, 997.0, 355.0]
pythonx2,y2,w2,h2 = cv2.boundingRect(conts_sorted[0]) (x2,y2,w2,h2) (12, 0, 798, 583)
pythonimport numpy as np, cv2 img2 = cv2.imread(paths[1])[:,:,::-1] h, w = img2.shape[:2] crop = img2[int(h*0.5):int(h*0.85), :] hsvc = cv2.cvtColor(crop, cv2.COLOR_RGB2HSV) lower_br = np.array([5, 80, 40]) upper_br = np.array([25, 255, 200]) mask = cv2.inRange(hsvc, lower_br, upper_br) mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, np.ones((3,3), np.uint8), iterations=1) mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((7,7), np.uint8), iterations=2) conts,_= cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) len(conts) 7
pythonconts_sorted = sorted(conts, key=lambda c: cv2.contourArea(c), reverse=True) areas=[cv2.contourArea(c) for c in conts_sorted[:3]] areas [105578.5, 709.0, 79.0]
pythonx,y,wc,hc = cv2.boundingRect(conts_sorted[0]) x,y,wc,hc (22, 0, 788, 233)
pythonimg1 = cv2.imread(paths[0])[:,:,::-1] hsv1 = cv2.cvtColor(img1, cv2.COLOR_RGB2HSV) # mask for missile yellowish (a bit pale) lower = np.array([15, 50, 120]) upper = np.array([45, 255, 255]) mask1 = cv2.inRange(hsv1, lower, upper) mask1 = cv2.morphologyEx(mask1, cv2.MORPH_OPEN, np.ones((3,3),np.uint8), iterations=1) mask1 = cv2.morphologyEx(mask1, cv2.MORPH_CLOSE, np.ones((5,5),np.uint8), iterations=2) conts,_ = cv2.findContours(mask1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) areas=sorted([cv2.contourArea(c) for c in conts], reverse=True)[:8] areas [36467.5, 3958.5, 2903.0, 2210.0, 2156.0, 2134.5, 1251.0, 1230.0]
pythonc=sorted(conts, key=lambda c: cv2.contourArea(c), reverse=True)[0] x,y,w,h=cv2.boundingRect(c) (x,y,w,h) (635, 80, 312, 339)
pythonimport matplotlib.pyplot as plt plt.imshow(img1) plt.gca().add_patch(plt.Rectangle((x,y), w,h, fill=False, linewidth=2)) plt.axis('off') (-0.5, 1055.5, 787.5, -0.5)
pythonimport numpy as np, cv2 img = cv2.imread(paths[1])[:,:,::-1] h,w = img.shape[:2] band = img[int(h*0.58):int(h*0.75), :] edges = cv2.Canny(cv2.cvtColor(band, cv2.COLOR_RGB2GRAY), 50, 150) # find horizontal projection of edges to decide leftmost/rightmost columns with many edges col_sum = edges.sum(axis=0) # threshold for significant columns thr = col_sum.max()*0.15 xs = np.where(col_sum>thr)[0] xs[:10], xs[-10:], xs.min(), xs.max(), w (array([26, 27, 56, 57, 59, 61, 62, 63, 65, 66]), array([216, 222, 261, 713, 771, 776, 778, 781, 783, 784]), 26, 784, 810)
pythonL2 = ratio2 * 11 L2 6.080474934036939
pythonimg3 = cv2.imread(paths[2])[:,:,::-1] h,w = img3.shape[:2] # Segment missile (yellow/greenish) hsv3 = cv2.cvtColor(img3, cv2.COLOR_RGB2HSV) lower = np.array([20, 50, 60]) upper = np.array([60, 255, 255]) mask3 = cv2.inRange(hsv3, lower, upper) mask3 = cv2.morphologyEx(mask3, cv2.MORPH_OPEN, np.ones((5,5), np.uint8), iterations=1) mask3 = cv2.morphologyEx(mask3, cv2.MORPH_CLOSE, np.ones((7,7), np.uint8), iterations=2) conts,_ = cv2.findContours(mask3, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) len(conts), sum(cv2.contourArea(c) for c in conts) (41, 280680.5)
pythonconts_sorted = sorted(conts, key=lambda c: cv2.contourArea(c), reverse=True)[:5] [(cv2.contourArea(c), cv2.boundingRect(c)) for c in conts_sorted] [(63353.5, (746, 605, 433, 249)), (34869.5, (79, 292, 623, 129)), (32836.0, (752, 274, 668, 78)), (30972.0, (1168, 530, 278, 280)), (28032.0, (825, 841, 449, 138))]
pythonimport matplotlib.pyplot as plt plt.figure(figsize=(8,5)) plt.imshow(img3); plt.axis('off') for c in conts_sorted[:5]: x,y,wc,hc = cv2.boundingRect(c) plt.gca().add_patch(plt.Rectangle((x,y), wc,hc, fill=False, linewidth=2))
pythonimg3 = cv2.imread(paths[2])[:,:,::-1] hsv3 = cv2.cvtColor(img3, cv2.COLOR_RGB2HSV) lower = np.array([20, 40, 50]) upper = np.array([70, 255, 255]) mask = cv2.inRange(hsv3, lower, upper) mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, np.ones((3,3),np.uint8), iterations=1) mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((5,5),np.uint8), iterations=2) conts,_=cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) boxes = [cv2.boundingRect(c) for c in conts if cv2.contourArea(c)>1000] # filter by y range around top missile band band = [250, 450] selected=[b for b in boxes if not (b[1]+b[3]<band[0] or b[1]>band[1]) and b[2]>150] len(selected), selected[:5] (2, [(77, 290, 650, 208), (738, 273, 689, 101)])
python# union width xs = [b[0] for b in selected] xe = [b[0]+b[2] for b in selected] missile_px3 = max(xe)-min(xs) missile_px3 1350
pythonimg3 = cv2.imread(paths[2])[:,:,::-1] h,w = img3.shape[:2] band = img3[int(h*0.55):int(h*0.8), :] edges = cv2.Canny(cv2.cvtColor(band, cv2.COLOR_RGB2GRAY), 50, 150) col_sum = edges.sum(axis=0) thr = col_sum.max()*0.15 xs = np.where(col_sum>thr)[0] xs.min(), xs.max(), w (11, 1905, 1920)
pythonvehicle_px3 = xs.max()-xs.min() ratio3 = missile_px3/vehicle_px3 ratio3 0.7127771911298838
按第一张图“车长=11 m”为尺子来量,计算方法是:
导弹实际长度 ≈ 11 m ×(导弹在图中的像素长度 ÷ 车辆在图中的像素长度)
我在图中量得的比例大致为:
图2(YJ-15):导弹≈419 px,车辆≈758 px → 比例≈0.553
→ 长度 ≈ 11 × 0.553 ≈ 6.1 米
图3(巡航导弹):导弹≈1350 px,车辆≈1894 px → 比例≈0.713
→ 长度 ≈ 11 × 0.713 ≈ 7.8 米
说明:由于透视、遮挡和画面模糊,结果有一定误差(大约±5%)。因此可取: