opencv-python-Convert distance into a heat map through the cv2.distanceTransform() function

This conversion can generally be used in the obstacle avoidance part of vision and SLAM to binarize the area that can be used, and then use the distanceTransform() function to achieve the gradient from the distance center to the outside of the target area, and then convert it into a visual gray Degree map and heat map can be used.

Principle analysis

(1) Binarization of target image

We first extract the HSV threshold of the target object through the HSV threshold regulator , and then use the cv2.inRangefunction to extract the threshold range of the area that the robot can pass through to obtain a two-dimensional plane binary map:

inRange_hsv = cv2.inRange(hsv, color_dist['gray']['Lower'], color_dist['gray']['Upper'])

Insert picture description here

(2) Gaussian filtering to remove noise

It can be seen that there are still many noise points in the image after the threshold is adjusted, so filter it:

gaussian_hsv = cv2.GaussianBlur(inRange_hsv, (3, 3), 1)  

Insert picture description here

(3) Convert the binarized image into a distance gray scale image

cv2.distanceTransform()The calculation result of the distance transformation function reflects the distance relationship between each pixel and the background (a pixel with a value of 0). usually:

dist = cv2.distanceTransform(src=gaussian_hsv, distanceType=cv2.DIST_L2, maskSize=5)

Insert picture description here

After processing, you need to use a cv2.convertScaleAbs()function to convert it back to its original uint8form, otherwise it will not be able to display the image, but just a gray window.

dist1 = cv2.convertScaleAbs(dist)
  • dist = cv2.convertScaleAbs(src[, dst[, alpha[, beta]]])
    • The optional parameter alphais the expansion coefficient,
    • betaIs a value added to the result,
    • The result distreturns a picture of uint8 type

Insert picture description here

Then normalize the uint8 type picture:

dist2 = cv2.normalize(dist, None, 255,0, cv2.NORM_MINMAX, cv2.CV_8UC1)

Insert picture description here

(4) Convert the distance gray scale image into a distance heat map

Through the cv2.applyColorMap()function, we can convert the grayscale image into a red-blue heatmap. When the value is 255, it is red, and when the value is 0, it is blue.

heat_img = cv2.applyColorMap(dist2, cv2.COLORMAP_JET)

Insert picture description here

Then take the maximum value of the RoI area and its coordinates:

costmap_roi = dist2[119:210,:]    #划定ROI区域,需要实际选取大小 现在表示选取 119-210行的位置 需要自己调整
min_value,max_value,minloc,maxloc = cv2.minMaxLoc(costmap_roi) #找最大的点
print(min_value,max_value,minloc,maxloc)

Output:

0.0 255.0 (151, 0) (0, 28)

Let's draw the point with the largest value in the figure to see the effect:

cv2.circle(heat_img2, (maxloc), 1, (0,255,0), -1)

It can be seen that it finds the point farthest from the obstacle in the RoI area very well.
Insert picture description here

Code

import cv2
import numpy as np
import matplotlib.pyplot as plt

color_dist = {
    
    'gray': {
    
    'Lower': np.array([0,0,46]), 'Upper': np.array([180,43,220])},
			  'red': {
    
    'Lower': np.array([0, 0, 0]), 'Upper': np.array([255, 93, 255])},
              'blue': {
    
    'Lower': np.array([100, 80, 46]), 'Upper': np.array([124, 255, 255])},
              'yellow': {
    
    'Lower': np.array([26, 43, 46]), 'Upper': np.array([34, 255, 255])},
              }

# img = cv2.imread("test_pictures/red_car.jpg")
img = cv2.imread("test_pictures/62.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
inRange_hsv = cv2.inRange(hsv, color_dist['gray']['Lower'], color_dist['gray']['Upper'])

gaussian_hsv = cv2.GaussianBlur(inRange_hsv, (3, 3), 1)  # 高斯滤波,去除小的噪声

dist = cv2.distanceTransform(src=gaussian_hsv, distanceType=cv2.DIST_L2, maskSize=5)
dist1 = cv2.convertScaleAbs(dist)
dist2 = cv2.normalize(dist, None, 255,0, cv2.NORM_MINMAX, cv2.CV_8UC1)
heat_img = cv2.applyColorMap(dist2, cv2.COLORMAP_JET)
costmap_roi = dist2[119:210,:]    #划定ROI区域,需要实际选取大小 现在表示选取 0-179行的位置 需要自己调整
heat_img2 = cv2.applyColorMap(costmap_roi, cv2.COLORMAP_JET)
min_value,max_value,minloc,maxloc = cv2.minMaxLoc(costmap_roi) #找最大的点
print(min_value,max_value,minloc,maxloc)
cv2.circle(heat_img2, (maxloc), 2, (0,255,0), -1)

cv2.imshow("img", img)
cv2.imshow("dist", dist)
cv2.imshow("dist1", dist1)
cv2.imshow("dist2", dist2)
cv2.imshow("heat_img", heat_img)

cv2.waitKey()

Guess you like

Origin blog.csdn.net/qq_45779334/article/details/114749524