美文网首页
positioning algorithm

positioning algorithm

作者: 求索_700e | 来源:发表于2019-05-23 14:13 被阅读0次

    定位算法

    import cv2

    import os

    import numpy as np

    BATTERY_WIDTH=1700

    BATTERY_HEIGHT=750

    BATTERY_SIZE_CHANGE_RATIO=0.2

    AREA_EXPAND_RATIO=1.1

    PIECES_WIDTH_NUM=6

    PIECES_HEIGHT_NUM=2

    PIECES_LENGTH=320

    CENTER_REGION_OFFSET={'left':150,'right':180,'top':100,'bottom':100}

    class Split_():

      def __init__(self):

            "input:"

            self.img_red=0

            self.img_blue=0

            self.img_green=0

            "output:"

            #self.affined_image_merged=0

            #self.centerRegion_gridX=[]

            #self.centerRegion_gridY=[]

            self.center_pieces=[]

            "debug:"

            self.image_name=""

      def obtain_contous(self):

            ret, thresh_map = cv2.threshold(self.img_red, 127,255, cv2.THRESH_BINARY)     

            image, contours, hier = cv2.findContours(thresh_map, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

            return contours

      def area_expand(self, p1, p2, iS_bottom_top_mode):##面积扩充函数

                      cx=(p1[0]+p2[0])/2

                      cy=(p1[1]+p2[1])/2

                      p1[0]=cx-abs(cx-p1[0])*AREA_EXPAND_RATIO

                      p2[0]=cx+abs(cx-p2[0])*AREA_EXPAND_RATIO

                      if iS_bottom_top_mode==True:

                          p1[1]=cy+abs(cy-p1[1])*AREA_EXPAND_RATIO

                          p2[1]=cy-abs(cy-p2[1])*ARA_EXPAND_RATIO

                      else:             

                          p1[1]=cy-abs(cy-p1[1])*AREA_EXPAND_RATIO

                          p2[1]=cy+abs(cy-p2[1])*AREA_EXPAND_RATIO

                      return p1,p2

      def find_four_corners(self,contours):##找出四个角点的坐标

          for c in contours:

              # find bounding box coordinates

              x,y,w,h = cv2.boundingRect(c)##x,y is the left_top point

              battery_size=BATTERY_HEIGHT*BATTERY_WIDTH 

              #print(w,h)   

              if w*h<battery_size*(1+BATTERY_SIZE_CHANGE_RATIO) and w*h>battery_size*(1-BATTERY_SIZE_CHANGE_RATIO):

                  # find minimum area

                rect = cv2.minAreaRect(c)

                # calculate coordinates of the minimum area rectangle

                box = cv2.boxPoints(rect)## return four points [(x,y)

                box = np.int0(box)

                left_bottom,right_top=self.area_expand(box[0],box[2],True)##box[0]=left_bottom,box[1]=left_top,box[2]=right_top

                left_top,right_bottom=self.area_expand(box[1],box[3],False)

                self.corner_points={"left_bottom": left_bottom,##定位出来的,在原图像中,电池的四个角点。

                                    "left_top":left_top,

                                    "right_top":right_top,

                                    "right_bottom":right_bottom

                                    }

                # draw contours

                #cv2.drawContours(self.img_c, [box], 0, (0,0, 255), 3)

                break

          '''

          cv2.namedWidow("contours",cv2.WINDOW_NORMAL)

          cv2.imshow("contours", self.img_c)

          cv2.imwrite("./_gird.jpg",self.img_c)

          cv2.waitKey()

          cv2.destroyAllWindows()

          '''

      def inverse_affine_transform(self):

              src_points =np.float32( [self.corner_points['left_top'], self.corner_points['right_top'], self.corner_points['left_bottom'],

                                self.corner_points['right_bottom']])##要被摳出來的原圖像中的四個角點。

              # 变换后分别在左上、右上、左下、右下四个点

              dst_points = np.float32([(0,0), (BATTERY_WIDTH, 0),

                                  (0, BATTERY_HEIGHT), (BATTERY_WIDTH, BATTERY_HEIGHT)])#摳出來後,映射到的四個角點位置,也就是圖像的大小。

              # 生成透视变换矩阵

              M = cv2.getPerspectiveTransform(src_points, dst_points)

              # 进行透视变换

              affined_red = cv2.warpPrspective(self.img_red, M, (BATTERY_WIDTH, BATTERY_HEIGHT),borderValue=(255,255,255)) 

              affined_green = cv2.warpPerspective(self.img_green, M, (BATTERY_WIDTH, BATTERY_HEIGHT),borderValue=(255,255,255)) 

              affined_blue = cv2.warpPerspective(self.img_blue, M, (BATTERY_WIDTH, BATTERY_HEIGHT),borderValue=(255,255,255)) 

              self.affined_image_merged=cv2.merge([affined_red,affined_green,affined_blue])

      def adjust_center_region(self):

              #self.center_adjusted_image_merged=self.affined_image_merged[CENTER_REGION_OFFSET['top']:BATTERY_HEIGHT-CENTER_REGION_OFFSET['bottom'], \

              #                                                    CENTER_REGION_OFFSET['left']:BATTERY_WIDTH-CENTER_REGION_OFFSET['right'],:]

              self.center_adjusted_width=BATTERY_WIDTH-CENTER_REGION_OFFSET['left']-CENTER_REGION_OFFSET['right']

              self.center_adjusted_height=BATTERY_HEIGHT-CENTER_REGION_OFFSET['top']-CENTER_REGION_OFFSET['bottom']

      def cal_overlap_ratio(self):

            def check(is_width,overlap_ratio):

                if overlap_ratio<0.05 or overlap_ratio>0.5:

                    if is_width:

                        raise ValueError("width overlao_ratio=%s is not reasonable"%overlap_ratio)

                    else:

                        raise ValueError("height overlao_ratio=%s is not reasonable"%overlap_ratio)\

                return overlap_ratio

            self.centerRegion_overlap_ratio_width=check(True, (PIECES_WIDTH_NUM*PIECES_LENGTH-self.center_adjusted_width)/((PIECES_WIDTH_NUM-1)*PIECES_LENGTH) )

            self.centerRegion_overlap_ratio_height=check(False, (PIECES_HEIGHT_NUM*PIECES_LENGTH-self.center_adjusted_height)/((PIECES_HEIGHT_NUM- \

                                                          1)*PIECES_LENGTH) )

      def construct_centerRegion_grid(self):

          self.centerRegion_gridX=[]

          self.centerRegion_gridY=[]

          for n in range(PIECES_WIDTH_NUM):

                self.centerRegion_gridX.append([CENTER_REGION_OFFSET['left']+int(n*PIECES_LENGTH*(1-self.centerRegion_overlap_ratio_width)), \

                      CENTER_REGION_OFFSET['left']+int(n*PIECES_LENGTH*(1-self.centerRegion_overlap_ratio_width)+PIECES_LENGTH)])## [start,end] positions

          for n in range(PIECES_HEIGHT_NUM):

                self.centerRegion_gridY.append([CENTER_REGION_OFFSET['top']+int(n*PIECES_LENGTH*(1-self.centerRegion_overlap_ratio_height)), \

                      CENTER_REGION_OFFSET['top']+int(n*PIECES_LENGTH*(1-self.centerRegion_overlap_ratio_height)+PIECES_LENGTH)])## [start,end] positions

          '''

          for x in range(0, PIECES_WIDTH_NUM):

              for y in range(0, PIECES_HEIGHT_NUM):

                    point_start= (self.centerRegion_gridX[x][0],self.centerRegion_gridY[y][0])

                    point_end=  (self.centerRegion_gridX[x][1],self.centerRegion_gridY[y][1])

                    cv2.circle(self.affined_image_merged, point_start, 1,  (0, 0, 255) , 5)

                    cv2.circle(self.affined_image_merged, point_end, 1,  (0, 255, 0) , 5)

          cv2.imwrite("./"+self.image_name, self.affined_image_merged)

          '''

      def cut_into_small_pieces(self):

          self.center_pieces=[]

          for y in range(0, PIECES_HEIGHT_NUM):

              for x in range(0, PIECES_WIDTH_NUM):

                    xmin=self.centerRegion_gridX[x][0]

                    ymin=self.centerRegion_gridY[y][0]

                    xmax=self.centerRegion_gridX[x][1]

                    ymax=self.centerRegion_gridY[y][1]

                    cut_img=self.affined_image_merged[ymin:ymax,xmin:xmax,:]

                    #cv2.imwrite("./output/"+self.image_name.split()[0]+"_"+str(idx)+".jpg", cut_img)

                    #idx+=1

                    self.center_pieces.append({"xmin":xmin,"ymin":ymin,"xmax":xmax,"ymax":ymax,"image":cut_img})

      def get_test_data(self, Split, img_red, img_green, img_blue):

          Split.img_red=img_red

          Split.img_green=img_green

          Split.img_blue=img_blue

          contours=Split.obtain_contours()

          Split.find_four_corners(contours)

          Split.inverse_affine_transform()

          Split.adjust_center_region()

          Split.cal_overlap_ratio()         

          Split.construct_centerRegion_grid()

          Split.cut_into_small_pieces()

          return self.affined_image_merged, self.center_pieces

    if __name__ == '__main__':

        img = cv2.imread("/home/ta/1.bmp", cv2.IMREAD_UNCHANGED)

        fname=os.listdir("/home/ta/Desktop/gs_for_test/blue/")

        Split=Split()

        for f in fname:

          Split.img_red=cv2.imread("/home/1/"+f, cv2.IMREAD_UNCHANGED)

          Split.img_green=cv2.imread("/home/2/"+f, cv2.IMREAD_UNCHANGED)

          Split.img_blue=cv2.imread("/home/3/"+f, cv2.IMREAD_UNCHANGED)

          Split.image_name=f

          contours=Split.obtain_contours()  ##二值化,获得轮廓信息,对轮廓进行最小外接矩形包围框提取,

          Split.find_four_corners(contours)## 根据包围框信息,以及约束条件,查找目标,排除干扰。

          Split.inverse_affine_transform()##逆透视投影变换,矫正并分离出目标。

          Split.adjust_center_region()

          Split.cal_overlap_ratio()         

          Split.construct_centerRegion_grid()

          Split.cut_into_small_pieces()

          print(f)

    相关文章

      网友评论

          本文标题:positioning algorithm

          本文链接:https://www.haomeiwen.com/subject/faivzqtx.html