ros地图的opencv处理(python)

原图:

代码: 

import cv2
import numpy as np
from PIL import Image
import rospy
class optimize:
    def __init__(self):
        rospy.init_node("popo2")


        #==============可调参数========================================================================
        self.pgmPath = rospy.get_param("pgmPath","/home/jjm1/noetic_in/auto/src/auto/map/mypgm.pgm")#文件路径
        self.bias = rospy.get_param("bias",6)#清理框选到的曲线部分的多余点所需的偏置
        self.bias1 = rospy.get_param("bias1",6)#曲线部分框选范围的偏置
        self.bias2 = rospy.get_param("bias2",0)#曲线部分框选范围的偏置
        self.bias3 = rospy.get_param("bias3",6)#曲线部分框选范围的偏置
        self.center = []
        self.im = self.read_img()
        self.imC = self.im.copy()
        self.all_on = rospy.get_param("all_on",int(self.im.shape[0]/8))#将所有需要的点框选的最小范围
        self.all_back = rospy.get_param("all_back",int(7*self.im.shape[0]/15))#将所有需要的点框选的最小范围
        self.all_left = rospy.get_param("all_left",int(self.im.shape[1]/4))#将所有需要的点框选的最小范围
        self.all_right = rospy.get_param("all_right",int(24*self.im.shape[1]/33))#将所有需要的点框选的最小范围
        self.outLeftBias = rospy.get_param("outLeftBias",23)#框选到的外层靠左部分的多余点所需的偏置
        self.outRightBias = rospy.get_param("outRightBias",23)#框选到的外层靠右部分的多余点所需的偏置
        self.outDownBias = rospy.get_param("outDownBias",23)#框选到的外层靠下部分的多余点所需的偏置
        self.innLeftBias = rospy.get_param("innLeftBias",27)#框选到的内层靠左部分的多余点所需的偏置
        self.innRightBias = rospy.get_param("innRightBias",30)#框选到的内层靠右部分的多余点所需的偏置
        self.innDownBias = rospy.get_param("innDownBias",23)#框选到的内层靠下部分的多余点所需的偏置 
        self.lineThick = rospy.get_param("lineThick",8)#线宽
        self.circleR = rospy.get_param("circleR",10)#圆的半径
        #============================================================================================



        #==============常参数=========================================================================
        self.horizontal = 0#排序的维度
        self.vertical = 1#排序的维度
        self.largeSmall = "max_to_min"#排序的顺序
        self.Smalllarge = "min_to_max"#排序的顺序
        #============================================================================================


        

        #=============获取所有点的坐标==================================================================
        self.center = self.all(self.im)
        #============================================================================================




        #=============画出外圈的右边,左边,下边==========================================================
        on1 = self.diff_sort(self.center,self.vertical,self.Smalllarge)[0][1]
        length1,w1,h1 = self.strongLRD(self.Smalllarge,self.horizontal,self.outLeftBias)#外左
        length2,w2,h2 = self.strongLRD(self.largeSmall,self.horizontal,self.outRightBias)#外右
        length3,_1,_2 = self.strongLRD(self.largeSmall,self.vertical,self.outDownBias)#外下
        #=============================================================================================



        
        #==============画出内圈的右边,左边,下边=========================================================
        w3,h3 = self.strong2LRD(self.Smalllarge,self.horizontal,length1,self.innLeftBias)#内左
        w4,_ = self.strong2LRD(self.largeSmall,self.horizontal,length2,self.innRightBias)#内右
        self.strong2LRD(self.largeSmall,self.vertical,length3,self.innDownBias)#内下
        #=============================================================================================




        #==============画出两条曲线=====================================================================
        self.imC[h1-self.bias2:h3+self.bias3,w3:w4],_ = self.part(self.im[h1-self.bias2:h3+self.bias3,w3:w4])#内曲线
        self.imC[on1:h1-self.bias1,w1:w2],center = self.part(self.im[on1:h1-self.bias1,w1:w2])#外曲线
        center = self.diff_sort(center,self.horizontal,self.Smalllarge)
        cv2.line(self.imC,(w1,h1),(w1+center[0][0],on1+center[0][1]),(0,0,0),thickness=self.lineThick)
        cv2.circle(self.imC, (w1,h1), self.circleR, (0, 0, 0), -1)
        cv2.line(self.imC,(w2,h2),(w1+center[len(center)-1][0],on1+center[len(center)-1][1]),(0,0,0),thickness=self.lineThick)
        cv2.circle(self.imC, (w2,h2), self.circleR, (0, 0, 0), -1) 
        #=============================================================================================


        #==============保存===========================================================================
        self.imC = cv2.cvtColor(self.imC,cv2.COLOR_RGB2GRAY)
        cv2.imwrite(self.pgmPath,self.imC)
        print("结束")
        #============================================================================================


#==========================读取图片====================================================================
    def read_img(self):
        im = Image.open(self.pgmPath)    # 读取文件
        im = cv2.cvtColor(np.asarray(im), cv2.COLOR_RGB2BGR)
        return im
#=====================================================================================================



#==========================获取点=====================================================================
    def all(self,im):
        roi = self.im[self.all_on:self.all_back,self.all_left:self.all_right]
        roi = cv2.medianBlur(roi,3)
        kernel = np.ones((3,3), np.uint8) 
        self.im[self.all_on:self.all_back,self.all_left:self.all_right]= cv2.morphologyEx(roi,cv2.MORPH_ERODE,kernel)
        mask,center,im = self.pic(im[self.all_on:self.all_back,self.all_left:self.all_right])
        contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
        for c in contours:
            (x, y, w, h) = cv2.boundingRect(c)
            cx,cy = int(x+self.all_left+w/2),int(self.all_on+y+h/2)
            cv2.circle(self.im, (cx, cy), 2, (0, 0, 0), -1)
            area = w*h
            center.append([cx,cy,area])
        center = self.diff_sort(center,self.horizontal,self.Smalllarge)
        return center
#======================================================================================================




#=========================画外圈=======================================================================
    def strongLRD(self,method,dir,bor_dis):
        center= self.diff_sort(self.center,dir,method)
        border = center[0][dir]
        border_all = []
        for i in center:
            if abs(i[dir]-border)<bor_dis:
                border_all.append(i)
        if dir == 0: 
            dir_inv = 1   
        else:
            dir_inv = 0
        border_all= self.diff_sort(border_all,dir_inv,self.Smalllarge)
        for i in range(len(border_all)-1):
            x0 = border_all[i][0]
            y0 = border_all[i][1]
            x1 = border_all[i+1][0]
            y1 = border_all[i+1][1]
            cv2.line(self.imC, (x0,y0),(x1,y1),[0,0,0],thickness=self.lineThick)
            cv2.circle(self.imC, (x1,y1), self.circleR, (0, 0, 0), -1) 
        return len(border_all),border_all[0][0],border_all[0][1]
#======================================================================================================





#========================画内圈=========================================================================
    def strong2LRD(self,method,dir,length,bor_dis):
        center= self.diff_sort(self.center,dir,method)
        border = center[length][dir]
        border_all = []
        for i in center:
            if abs(i[dir]-border)<bor_dis:
                border_all.append(i)
        if dir == 0: 
            dir_inv = 1   
        else:
            dir_inv = 0
        border_all= self.diff_sort(border_all,dir_inv,self.Smalllarge)
        border_all.pop(0)
        border_all.pop()
        for i in range(len(border_all)-1):
            x0 = border_all[i][0]
            y0 = border_all[i][1]
            x1 = border_all[i+1][0]
            y1 = border_all[i+1][1]
            cv2.line(self.imC, (x0,y0),(x1,y1),[0,0,0],thickness=self.lineThick)
            cv2.circle(self.imC, (x1,y1), self.circleR, (0, 0, 0), -1) 
        return border_all[0][0],border_all[1][1]
#=======================================================================================================




#==========================画曲线========================================================================
    def part(self,im):
        mask,center,im = self.pic(im)
        contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
        for c in contours:
            (x, y, w, h) = cv2.boundingRect(c)
            cx,cy = int(x+w/2),int(y+h/2)
            area = w*h
            center.append([cx,cy,area])
        center = self.diff_sort(center,self.vertical,self.largeSmall)
        for i in center:
            if im.shape[0]-i[1]<self.bias:
                center.remove(i) 
        center.pop(0)
        center = self.diff_sort(center,self.horizontal,self.Smalllarge)
        for i in range(len(center)-1):
            cv2.line(im,(center[i][0],center[i][1]),(center[i+1][0],center[i+1][1]),(0,0,0),thickness=self.lineThick)
            cv2.circle(im, (center[i][0],center[i][1]), self.circleR, (0, 0, 255), -1)            
        center = self.diff_sort(center,self.vertical,self.largeSmall) 
        return im,center
#========================================================================================================




#==========================滤波和形态学处理=================================================================
    def pic(self,im):
        center = []
        im = cv2.medianBlur(im,5)
        kernel = np.ones((5,5), np.uint8) 
        im= cv2.morphologyEx(im,cv2.MORPH_ERODE,kernel)
        lower_black = np.array([0,0,0]) 
        upper_black = np.array([180,255,46])
        mask = cv2.inRange(im, lower_black, upper_black)
        return mask,center,im
#=========================================================================================================



#==========================排序============================================================================
    def diff_sort(self,center,dir,method):    
        for i in range(len(center)):
            j = i + 1
            for j in range(len(center)):
                if method == self.largeSmall:
                    cat = center[i][dir]<center[j][dir]
                elif method == self.Smalllarge:
                    cat = center[i][dir]>center[j][dir]
                if cat==False:
                    center[i][:],center[j][:] = center[j][:],center[i][:]
        return center
#==========================================================================================================
    


    


if __name__ == "__main__":
    popo = optimize()



处理后:

猜你喜欢

转载自blog.csdn.net/qq_58060770/article/details/127718068