当前位置:   article > 正文

使用yolo识别模型对比两张图片并标记不同

使用yolo识别模型对比两张图片并标记不同

目录

需求:

难点:

思路:

代码:

1、stage1.py

结果:

2、stage2.py

结果:

3、stage3.py

结果:

总结:


需求:

无人机视角下,不同时间同一地点拍摄的两张图片,比对后,将不同标注在第一张图片上,比如说违建,第一次拍摄的时候发现有违建,过段时间需要检查这个违建拆除了没有于是再拍摄一张,开发者要做的是,比对两张图片的违建情况并标记出来

难点:

两张图片拍摄角度不完全一样、图片大小可能存在差异、图片上除了违建不同之外可能存在其他不同(比如不同时间下该地点行人或者车辆停放之类的不同,这种是不需要标记的)

思路:

1、将两张照片旋转对齐,使大小角度一致

2、将处理后的照片使用模型识别(需要提前做好模型训练),专门识别出违建目标

3、比对两张图片识别出来的目标,将多出来的目标标红,少的目标标绿

代码:

1、stage1.py
  1. import cv2
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. # stage1 将图片比对原始图片,转化大小角度之后保存
  5. # 加载图片A和B
  6. imgA = cv2.imread('../images/origin.jpg')
  7. imgB = cv2.imread('../images/update1.jpg')
  8. # 特征点检测和匹配
  9. # 创建了一个 ORB 检测器对象。
  10. detector = cv2.ORB_create()
  11. # orb.detectAndCompute() 函数来检测关键点并计算描述符。
  12. keypointsA, descriptorsA = detector.detectAndCompute(imgA, None)
  13. keypointsB, descriptorsB = detector.detectAndCompute(imgB, None)
  14. # 创建基于暴力匹配的特征匹配器
  15. matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
  16. # 使用 bf.match(des1, des2) 进行特征匹配,并根据距离排序匹配结果。
  17. matches = matcher.match(descriptorsA, descriptorsB)
  18. # sorted() 函数对特征匹配结果进行排序。在这里,matches 是一个特征匹配对象的列表,每个对象包含了匹配的两个特征点以及它们之间的距离信息。
  19. matches = sorted(matches, key=lambda x: x.distance)
  20. pointsA = np.float32([keypointsA[m.queryIdx].pt for m in matches]).reshape(-1, 1, 2)
  21. pointsB = np.float32([keypointsB[m.trainIdx].pt for m in matches]).reshape(-1, 1, 2)
  22. # 对齐图像B
  23. M, mask = cv2.findHomography(pointsB, pointsA, cv2.RANSAC, 5.0)
  24. # 对一张图像进行透视变换,使其与另一张图像对齐
  25. alignedImgB = cv2.warpPerspective(imgB, M, (imgA.shape[1], imgA.shape[0]))
  26. #cv2.imwrite("stage1.png", alignedImgB)
  27. # 找到重叠区域的边界
  28. mask_gray = cv2.cvtColor(alignedImgB, cv2.COLOR_BGR2GRAY)
  29. ret, thresh = cv2.threshold(mask_gray, 1, 255, cv2.THRESH_BINARY)
  30. contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  31. x, y, w, h = cv2.boundingRect(contours[0])
  32. # 裁剪出图二重叠部分
  33. overlap_region2 = alignedImgB[y:y+h, x:x+w]
  34. # 保存结果
  35. cv2.imwrite('overlap_region2.jpg', overlap_region2)
  36. # 裁剪出图一重叠部分
  37. overlap_region1 = imgA[y:y+h, x:x+w]
  38. # 保存结果
  39. cv2.imwrite('overlap_region1.jpg', overlap_region1)
结果:

2、stage2.py
  1. # stage2 将原始图片的彩钢瓦识别后提取
  2. import cv2
  3. from ultralytics import YOLO
  4. from PIL import Image
  5. model = YOLO('../../illegal-building/train2560_100_3/weights/best.pt')
  6. image = Image.open('../matched_org_image1.jpg')
  7. image2 = Image.open('../matched_org_image2.jpg')
  8. results = model.predict(source=image2, save=True, save_txt=True, classes=0, line_width=5, iou=0.1)
  9. print("======")
  10. print(results)
结果:

比对识别出来的目标框

3、stage3.py
  1. # stage3 比对两张图片的识别框
  2. # 相比与原始图像多出来的框,和少的框,绘制到第二张图片上
  3. # 多出来的用红色标记、少了的用绿色标记
  4. import cv2
  5. # 将读取的标注信息放的数组里
  6. def readtxttoarray(path):
  7. array = []
  8. # 打开文件进行读取
  9. with open(path, 'r') as file:
  10. # 逐行读取文件内容并添加到数组中
  11. for line in file:
  12. rects = [float(rect) for rect in line.strip().split(" ")]
  13. array.append(rects) # 去除每行末尾的换行符并添加到数组中
  14. return array
  15. def is_within_range(num1, num2):
  16. """
  17. 判断两个数之间的误差是否在指定阈值范围内
  18. :param num1: 第一个数
  19. :param num2: 第二个数
  20. :param threshold: 误差阈值,默认为0.02
  21. :return: 如果两个数之间的误差小于等于阈值,则返回True,否则返回False
  22. """
  23. # 计算两个数的差的绝对值
  24. diff = abs(num1 - num2)
  25. threshold = 0.02
  26. # 判断差值是否小于等于阈值
  27. return diff <= threshold
  28. def check_intersection(box1, box2):
  29. # 提取边界框坐标
  30. a1, x1, y1, w1, h1 = box1
  31. a2, x2, y2, w2, h2 = box2
  32. # 计算水平方向上的投影
  33. x_overlap = max(0, min(x1 + w1, x2 + w2) - max(x1, x2))
  34. # 尺码、颜色:m粉白
  35. # 计算垂直方向上的投影
  36. y_overlap = max(0, min(y1 + h1, y2 + h2) - max(y1, y2))
  37. # 如果两个投影都有重叠,则说明存在交集
  38. return x_overlap > 0 and y_overlap > 0
  39. # 如果每个标注点相差在0.02之间则认为是同一个框
  40. # 获取在原始图片上有但是在更新后的图片上没有的标注信息
  41. def getdiffbox(org_content, update_content):
  42. retbox = []
  43. for box in org_content:
  44. a = True;
  45. for rect in update_content:
  46. # 计算两个框是否相交
  47. if check_intersection(box, rect):
  48. # if (is_within_range(box[1], rect[1])and is_within_range(box[2], rect[2])and is_within_range(box[3], rect[3])and is_within_range(box[4], rect[4])):
  49. a = False
  50. break
  51. if a:
  52. retbox.append(box)
  53. return retbox
  54. category = {
  55. 0: "weijian",
  56. 1: "lajiduifang",
  57. 2: "zawuduifang",
  58. 3: "piaofuwu",
  59. 4: "shuishenzhiwu",
  60. 5: "shatuluolu",
  61. 6: "jianzhulaji",
  62. 7: "lagua",
  63. 8: "zhongzhi",
  64. 9: "jieganfenshao",
  65. }
  66. # 将得到的框绘制到第二张图上
  67. # 读取图像
  68. def drawboxonfile(path, diff_box, color):
  69. img = cv2.imread(path)
  70. for box in diff_box:
  71. x_center = float(box[1]) * img.shape[1] # 相对于图像宽度的中心坐标
  72. y_center = float(box[2]) * img.shape[0] # 相对于图像高度的中心坐标
  73. width = float(box[3]) * img.shape[1] # 相对于图像宽度的边界框宽度
  74. height = float(box[4]) * img.shape[0] # 相对于图像高度的边界框高度
  75. # 计算边界框的左上角和右下角坐标
  76. x1 = int(x_center - width / 2)
  77. y1 = int(y_center - height / 2)
  78. x2 = int(x_center + width / 2)
  79. y2 = int(y_center + height / 2)
  80. # 绘制边界框和类别名称
  81. cv2.rectangle(img, (x1, y1), (x2, y2), color, 3)
  82. cv2.putText(img, category[(int)(box[0])], (x1, y1 - 10),
  83. cv2.FONT_HERSHEY_SIMPLEX,
  84. 1,
  85. color,
  86. 4, )
  87. # 显示带有标注信息的图像
  88. cv2.imwrite('result.jpg', img)
  89. cv2.waitKey(0)
  90. cv2.destroyAllWindows()
  91. # 定义一个空数组用于存储文件内容
  92. org_content = readtxttoarray("runs/detect/predict5/labels/matched_org_image1.txt")
  93. # 定义一个空数组用于存储文件内容
  94. #
  95. update_content = readtxttoarray("runs/detect/predict4/labels/matched_org_image2.txt")
  96. diff_box = getdiffbox(org_content, update_content)
  97. raise_box = getdiffbox(update_content, org_content)
  98. drawboxonfile("../matched_org_image1.jpg", diff_box, (0, 255, 0))
  99. drawboxonfile("result.jpg", raise_box, (0, 0, 255))
结果:

总结:

由于模型精确度不高,结果差强人意,但这个思路应该有可以借鉴的地方,遂整理一下

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/484162
推荐阅读
相关标签
  

闽ICP备14008679号