Facebook
From s, 8 Months ago, written in Python.
Embed
Download Paste or View Raw
Hits: 243
  1. import time
  2. import cv2
  3. import threading
  4. import tensorflow as tf
  5. import json
  6. from keras.layers import Conv1D, MaxPooling1D, Flatten, Dense, Dropout, BatchNormalization, Activation, Add, GlobalAveragePooling1D
  7. from keras.preprocessing.image import ImageDataGenerator
  8. from keras.optimizers import Adam
  9. import math
  10.  
  11.  
  12. class ConnectingRectangle():
  13.     MAX_HORIZONTAL_ANGLE = math.tan(math.radians(25) )
  14.     MAX_VERTICAL_ANGLE = math.tan(math.radians(50) )
  15.     MIN_DISTANCE_BETWEEN_HORIZONTAL_EDGES = 100  
  16.        
  17.     def __init__(self, list_ending_puncts = None):
  18.         self.list_ending_puncts = list_ending_puncts
  19.         self.measure_light_obj = MeasureLightAround()
  20.     # def detecting_biggest_rectangle(list_ending_puncts):
  21.     #     # list_ending_puncts ->  x1, y1, x2, y2
  22.     #     pass
  23.  
  24.     @staticmethod
  25.     def _find_tan( list_pucts ):
  26.         return (list_pucts[1] -  list_pucts[3] ) / (list_pucts[0] - list_pucts[2])
  27.    
  28.    
  29.    
  30.     def categorize_edges(self):
  31.         self.likely_edges_horizontal = [[],[]] # right -> 0;  left -> 1
  32.         self.likely_edges_vertical = [[], []] # right -> 0;  left -> 1
  33.        
  34.        
  35.         for id_contour in range(len(self.list_ending_puncts)):
  36.             tan_ = ConnectingRectangle._find_tan(self.list_ending_puncts[id_contour])  
  37.            
  38.             if abs(tan_) <= ConnectingRectangle.MAX_HORIZONTAL_ANGLE:
  39.                 if tan_ > 0:
  40.                     self.likely_edges_horizontal[0].append(self.list_ending_puncts[id_contour])
  41.            
  42.                 else: self.likely_edges_horizontal[1].append(self.list_ending_puncts[id_contour])
  43.                
  44.             elif abs(tan_ ) >= ConnectingRectangle.MAX_VERTICAL_ANGLE:
  45.                 if tan_ > 0 :
  46.                     self.likely_edges_vertical[0].append(self.list_ending_puncts[id_contour])
  47.                 else: self.likely_edges_vertical[1].append(self.list_ending_puncts[id_contour])
  48.         return self.likely_edges_horizontal, self.likely_edges_vertical
  49.    
  50.    
  51.     @staticmethod
  52.     def verify_distance(self, list_sided_edges):
  53.         distances = []
  54.         max_distance_ids = 0
  55.         max_distance_val = None
  56.         if len(list_sided_edges) == 0 : return distances, max_distance_ids, max_distance_val        
  57.            
  58.         for id_contour_base in range(len(list_sided_edges)-1):
  59.            
  60.             for id_contour_adjusted in range(id_contour_base+1,len(list_sided_edges) ):
  61.                  
  62.                 distance_between_up_down_edges = abs(list_sided_edges[id_contour_base][3] - list_sided_edges[id_contour_adjusted][3])
  63.                
  64.                 if distance_between_up_down_edges  > ConnectingRectangle.MIN_DISTANCE_BETWEEN_HORIZONTAL_EDGES :
  65.                    
  66.                     if distance_between_up_down_edges > max_distance_val:
  67.                         max_distance_ids = [id_contour_base,id_contour_adjusted]  
  68.                         max_distance_val = distance_between_up_down_edges
  69.                    
  70.                     distances.append([id_contour_base,id_contour_adjusted, abs(distance_between_up_down_edges )] )
  71.        
  72.         return distances, max_distance_id, max_distance_val            
  73.  
  74.  
  75.            
  76.     def horizontal_edges_containers(self, ):
  77.         if  len(self.likely_edges_horizontal[0])  + len(self.likely_edges_horizontal[1]) <=  2:
  78.            
  79.             # będzie zero kontur
  80.             if len(self.likely_edges_horizontal[0] ) == 0  and len(self.likely_edges_horizontal[1] ) == 0:
  81.                 return []
  82.            
  83.             if len(self.likely_edges_horizontal[0] ) == 1 and len(self.likely_edges_horizontal[1] ) == 0:
  84.                 return self.likely_edges_horizontal[0]
  85.            
  86.             if len(self.likely_edges_horizontal[0] ) == 0 and len(self.likely_edges_horizontal[1] ) == 1:
  87.                 return self.likely_edges_horizontal[1]
  88.            
  89.             # będzie po jednej konturze
  90.             if len(self.likely_edges_horizontal[0] ) == 1 and len(self.likely_edges_horizontal[1] ) == 1:
  91.                 id_lenghter = np.argmax( [ ConnectingRectangle.lenght_contour(self.likely_edges_horizontal[0]), ConnectingRectangle.lenght_contour(self.likely_edges_horizontal[1]) ] )
  92.                 return self.likely_edges_horizontal[id_lenghter ]          
  93.        
  94.         else:
  95.             distances_right, max_distance_id_right, max_distance_val_right  = ConnectingRectangle.verify_distance(self.likely_edges_horizontal[0])
  96.             distances_left, max_distance_id_left, max_distance_val_left  = ConnectingRectangle.verify_distance(self.likely_edges_horizontal[1])
  97.            
  98.             if max_distance_val_right !=  0 and max_distance_val_left  ==  0:
  99.                 return [ self.likely_edges_horizontal[0][distances_right[0]] , self.likely_edges_horizontal[0][distances_right[1]] ]
  100.            
  101.             elif max_distance_val_right ==  0 and max_distance_val_left  !=  0:
  102.                 return [ self.likely_edges_horizontal[1][distances_left[0]] , self.likely_edges_horizontal[1][distances_left[1]] ]
  103.            
  104.             elif max_distance_val_right !=  0  and max_distance_val_left != 0 :
  105.                 id_max_distance = np.argmax([max_distance_val_right,max_distance_val_left])
  106.                 if id_max_distance == 0 :  
  107.                     return [ self.likely_edges_horizontal[0][distances_right[0]] , self.likely_edges_horizontal[0][distances_right[1]] ]
  108.                
  109.                 elif id_max_distance == 1 :  
  110.                     return [ self.likely_edges_horizontal[1][distances_left[0]] , self.likely_edges_horizontal[1][distances_left[1]]]
  111.  
  112.  
  113.     def vertical_edges(self,):
  114.          self.edges_with_equati
  115.         self.pairs_hor_edges = []
  116.          self.puncts_of_interseti
  117.          all_c
  118.         all_conts.extend(self.likely_edges_vertical[1])
  119.         # .extend(self.likely_edges_vertical[1])
  120.         for id_, contour in enumerate(all_conts) :
  121.              directi
  122.             self.edges_with_equation[contour] = direction_factors  
  123.        
  124.        
  125.         for contour_right in range( len( self.likely_edges_vertical[0] ) ) :
  126.            
  127.             for contour_left in range( len( self.likely_edges_vertical[1] )) :
  128.                
  129.                 x, y = ConnectingRectangle.puncts_of_intersection(self.edges_with_equation[contour_right],self.edges_with_equation[contour_left])  
  130.                 if x is None and y is None:
  131.                     return 0,0
  132.                                  
  133.                 if y > img_height: # daj tutaj adn. że to wynika z geometrii perspektywicznej
  134.                    
  135.                     self.pairs_hor_edges.append([ contour_right, contour_left ] )
  136.                     self.puncts_of_intersetion_horizontal_edges.append(y)
  137.              
  138.         return self.pairs_hor_edges
  139.  
  140.            
  141.     def vertical_edges_containers(self, ):
  142.        
  143.         if  len(self.likely_edges_vertical[0] ) >= 1  and len(self.likely_edges_vertical[1] ) >= 1:
  144.             self.vertical_edges()
  145.             if len( self.pairs_hor_edges ) ==1 :
  146.                 return  self.pairs_hor_edges[0]
  147.            
  148.             elif len( self.pairs_hor_edges) > 1:
  149.                 #tutaj tworzymy te kolory
  150.                 return self.measure_light_obj.pick_max_var_surronded_area(self.pairs_hor_edges)
  151.            
  152.             elif len( self.pairs_hor_edges ) == 0 :
  153.                 pass
  154.                 # problem  tutaj sprawdz czy może te które są njablizęj a jeśli nie to odrzuć wsztskie    
  155.  
  156.         elif len(self.likely_edges_vertical[0] ) == 0  and len(self.likely_edges_vertical[1] ) == 0:
  157.             return []
  158.            
  159.         elif len(self.likely_edges_vertical[0] ) == 0  and len(self.likely_edges_vertical[1] ) == 1:
  160.             return self.likely_edges_vertical[1]
  161.        
  162.         elif len(self.likely_edges_vertical[0] ) == 1  and len(self.likely_edges_vertical[1] ) == 0:
  163.             return self.likely_edges_vertical[0]
  164.        
  165.    
  166.     @staticmethod
  167.     def lenght_contour(contour):
  168.         return np.sqrt( ( contour[0] - contour[2] ) ** 2 + ( contour[1] - contour[3] ) ** 2  )
  169.    
  170.  
  171.     @staticmethod
  172.     def equation_line(bordered_puncts):
  173.         a = (bordered_puncts[1] - bordered_puncts[3]) / (bordered_puncts[0] - bordered_puncts[2])  
  174.         b = bordered_puncts[1] - a*bordered_puncts[0]
  175.         return [ a,b  ]
  176.    
  177.     @staticmethod
  178.     def puncts_of_intersection(a1,b1,a2,b2):
  179.         try:
  180.             x = (b2-b1) / (a1 - a2)
  181.             y = x * a1 + b1
  182.             return x, y
  183.         except ZeroDivisionError:
  184.             return None, None    
  185.    
  186.     @staticmethod
  187.     def sum_from_1_to_n(n):
  188.         return n(n+1)/2
  189.    
  190.     @staticmethod
  191.     def mid_punct(contour ):
  192.         x = int( ( contour[0] + contour[2]) / 2 )
  193.         y = int( ( contour[0] + contour[2]) / 2 )
  194.         return x, y
  195.    
  196.  
  197.     def extreme_val_hor_edges(self,a,b):
  198.         x = ( ConnectingRectangle.img_height - b ) / a
  199.        
  200.         if a > 0 :            
  201.             if b> 0 :
  202.                 return (0,b) , (x,ConnectingRectangle.img_height)
  203.             else:
  204.                 x1 = -b/a
  205.                 return (0,x1) , (x,ConnectingRectangle.img_height)
  206.         else:
  207.  
  208.             x_hor = -b/a
  209.  
  210.             if  x_hor > ConnectingRectangle.img_width:
  211.                 y1 = ConnectingRectangle.img_width * a + b
  212.                 return (x,ConnectingRectangle.img_height), (ConnectingRectangle.img_width, y1)
  213.            
  214.             else:
  215.                 return (x,ConnectingRectangle.img_height), (x_hor, 0)
  216.  
  217.        
  218.     def extreme_val_ver_edges(self,a,b):
  219.        
  220.         if a> 0 :
  221.             if b> 0 :
  222.                 y = ConnectingRectangle.img_width * a + b
  223.                 if y > ConnectingRectangle.img_height :
  224.                     x = ( ConnectingRectangle.img_height - b ) /a
  225.                     return (0, b), (x, ConnectingRectangle.img_height )
  226.                 else: return (0, b), (ConnectingRectangle.img_width, y)
  227.             elif b< 0 :
  228.                 x = -b/a
  229.                 y = ConnectingRectangle.img_width * a + b
  230.                 return (x, 0), (ConnectingRectangle.img_width, y)
  231.            
  232.         elif a< 0 :
  233.             y = a * ConnectingRectangle.img_width + b
  234.             if b > ConnectingRectangle.img_height :
  235.                 x = (ConnectingRectangle.img_height - b)/a
  236.                 return (x,ConnectingRectangle.img_height) , (ConnectingRectangle.img_width, y)
  237.             else:
  238.                 return (0, b), ( ConnectingRectangle.img_width, y)
  239.            
  240.                        
  241.     def _crop_image_without_hor(self, vertical_edges):
  242.        
  243.         ver1, ver2 = ConnectingRectangle.equation_line(vertical_edges[0]), ConnectingRectangle.equation_line(vertical_edges[1])
  244.        
  245.         pt1, pt2 = self.extreme_val_ver_edges(*ver1)
  246.         pt3, pt4 = self.extreme_val_ver_edges(*ver2)
  247.        
  248.         return [pt1, pt2, pt3, pt4]
  249.    
  250.     def _crop_image_two_ver_one_hor(self, vertical_edges,horizontal_edges):
  251.        
  252.         ver1, ver2 = ConnectingRectangle.equation_line(vertical_edges[0]), ConnectingRectangle.equation_line(vertical_edges[1])
  253.         a_hor ,b_hor = ConnectingRectangle.equation_line(horizontal_edges[0])
  254.        
  255.         pt3 = ConnectingRectangle.puncts_of_intersection(a_hor, b_hor, *ver1)    
  256.         pt4 = ConnectingRectangle.puncts_of_intersection(a_hor, b_hor, *ver2)    
  257.        
  258.         pt1 = self.extreme_val_ver_edges(*ver1)              
  259.         pt2  = self.extreme_val_ver_edges(*ver2)  
  260.  
  261.        
  262.         if a_hor > 0 :
  263.             min_x_intersection = min([pt3,pt4], key = lambda x: x[0] )
  264.        
  265.             if pt1[0][0] < min_x_intersection: pt1_choice = pt1[0]
  266.             else: pt1_choice =  pt1[1]
  267.             if pt2[0][0] < min_x_intersection: pt2_choice = pt2[0]
  268.             else: pt2_choice =  pt2[1]
  269.                      
  270.         else:
  271.              max_x_intersecti key = lambda x: x[0] )
  272.            
  273.             if pt1[0][0] > max_x_intersection: pt1_choice = pt1[0]
  274.             else: pt1_choice =  pt1[1]
  275.             if pt2[0][0] >  max_x_intersection: pt2_choice = pt2[0]
  276.             else: pt2_choice =  pt2[1]
  277.  
  278.         return [pt1_choice, pt2_choice, pt3, pt4]
  279.    
  280.    
  281.  
  282.     def _crop_image_one_ver_two_hor(self, vertical_edges,horizontal_edges):
  283.    
  284.         hor1, hor2 = ConnectingRectangle.equation_line(horizontal_edges[0]), ConnectingRectangle.equation_line(horizontal_edges[1])
  285.        
  286.         a_ver ,b_ver = ConnectingRectangle.equation_line(vertical_edges[0])
  287.        
  288.         pts1 = self.extreme_val_hor_edges(*hor1)
  289.         pts2 = self.extreme_val_hor_edges(*hor2)
  290.         pt3 = ConnectingRectangle.puncts_of_intersection(a_ver, b_ver, *hor1)    
  291.         pt4 = ConnectingRectangle.puncts_of_intersection(a_ver, b_ver, *hor2)  
  292.        
  293.         if vertical_edges > 0.55 * ConnectingRectangle.img_height:
  294.             pt1 = min(pts1, key = lambda x: x[1])
  295.             pt2 = min(pts1, key = lambda x: x[1])
  296.  
  297.         elif vertical_edges  < 0.45 * ConnectingRectangle.img_height:
  298.             pt1 = max(pts1, key = lambda x: x[1])
  299.             pt2 = max(pts1, key = lambda x: x[1])
  300.         return [pt1, pt2, pt3, pt4 ]
  301.    
  302.         #Mozna tu dodać jakby ifa
  303.    
  304.         # else:
  305.         #     pass # coś zjebanego
  306.    
  307.     def _crop_image_two_hor_two_ver(self, vertical_edges,horizontal_edges):
  308.         corner_puncts = []
  309.          vertical_lines_equati ConnectingRectangle.equation_line(vertical_edges[1])]
  310.          horiz equation_line(horizontal_edges[0])
  311.        
  312.         for ver_equa in  vertical_lines_equations:        
  313.             for hor_equa in horizontal_lines_equations:
  314.        
  315.                 corner_puncts.append(ConnectingRectangle.puncts_of_intersection(*ver_equa, *hor_equa) )
  316.         return corner_puncts
  317.  
  318.     def _crop_image_without_edges(self,):
  319.         return [(0,ConnectingRectangle.img_height) , (ConnectingRectangle.img_width, 0),(ConnectingRectangle.img_width,ConnectingRectangle.img_height) , (0,0)]
  320.    
  321.     def _calculate_corner_puncts(self, vertical_edges, horizontal_edges):
  322.  
  323.         if vertical_edges is None and horizontal_edges is None:
  324.             print(f'vertical_edges {vertical_edges} horizontal_edges {horizontal_edges}')
  325.             return self._crop_image_without_edges() # najgorszy przypadek
  326.        
  327.         elif  len( vertical_edges) == 2 and len( horizontal_edges ) == 2 :
  328.             return self._crop_image_two_hor_two_ver(vertical_edges, horizontal_edges)
  329.  
  330.         elif  len( vertical_edges) == 2 and len( horizontal_edges ) == 1 :
  331.             return self._crop_image_two_ver_one_hor(vertical_edges , horizontal_edges)
  332.  
  333.         elif len(vertical_edges) == 2 and len( horizontal_edges ) == 0 :
  334.             return self._crop_image_without_hor(vertical_edges)
  335.        
  336.         elif len(verical_edges ) ==  1 and len(horizontal_edges ) == 2:
  337.             return self._crop_image_one_ver_two_hor(verical_edges , horizontal_edges)
  338.        
  339.         else:
  340.             print(f'vertical_edges {vertical_edges} horizontal_edges {horizontal_edges}')
  341.             return self._crop_image_without_edges() # cały obraz
  342.        
  343.     def find_corner_puncts_img(self,lines_edges):
  344.         self.list_ending_puncts = lines_edges
  345.        
  346.         self.categorize_edges()
  347.         self.ver_  =  self.vertical_edges_containers()
  348.        
  349.         self.hor_ = self.horizontal_edges_containers()
  350.        
  351.         # tutaj napisz dodaj argumenty
  352.        
  353.         return self._calculate_corner_puncts(self.ver_, self.hor_)
  354.        
  355.        
  356.        
  357.        
  358. class MeasureLightAround():
  359.      def __init__(self,c :
  360.          self.c
  361.        
  362.     def kernel_light_measure(self, x,y,side,  ):
  363.         half_kernel = self.kernel_size//2
  364.         sum_pixel = 0
  365.        
  366.         for id_ in range(self.kernel_size):
  367.             if side == "left":
  368.                 current_y = y - half_kernel + id_
  369.             elif side == "right":
  370.                 current_x = x - half_kernel + id_
  371.  
  372.             for amount_row in range(self.kernel_size - id_ ):
  373.                
  374.                 if side == "left":
  375.                     current_x = x - half_kernel  + amount_row + id_
  376.        
  377.                 elif side == "right" :
  378.                     current_y = y - half_kernel  + amount_row + id_
  379.        
  380.                 if current_y > ConnectingRectangle.img_height and current_y >= 0 and  current_x <= ConnectingRectangle.img_width  and current_x >= 0 :
  381.                     sum_pixel += img[current_x, current_y]
  382.        
  383.                 else: sum_pixel += 255
  384.        
  385.         return sum_pixel / ConnectingRectangle.sum_from_1_to_n(self.kernel_size)
  386.  
  387.    
  388.     def check_approximation_pixel(self, contour, ):
  389.         x , y = ConnectingRectangle.mid_punct(contour)
  390.        
  391.         mean_right =  self.kernel_light_measure(x, y, side = "right")
  392.         mean_left = self.kernel_light_measure(x, y, side = "left")
  393.        
  394.         return [mean_right, mean_left]
  395.    
  396.     def pick_max_var_surronded_area(self, pairs_contours, ):
  397.         self.var_values = []
  398.         for right_cont, left_cont in pairs_contours:
  399.             right_area = self.check_approximation_pixel(right_cont)
  400.             left_area = self.check_approximation_pixel(left_cont)
  401.             self.var_values.append( np.var(right_area.extend(left_area)) )
  402.        
  403.         return pairs_contours[ np.argmax(self.var_values) ], self.var_values  
  404.    
  405.    
  406.    
  407. data = [[467, 366, 506, 49], [439, 371, 659, 374], [24, 148, 97, 385], [515, 373, 567, 43], [516, 373, 568, 43], [94, 380, 356, 393], [436, 375, 675, 379], [96, 385, 418, 385]]      
  408. connecting_obj = ConnectingRectangle()
  409. connecting_obj.find_corner_puncts_img(data)
  410.    
  411.    
  412.     # def horizontal_down(a,b ):
  413.     #     x = -b/ a
  414.     #     if x>  ConnectingRectangle.img_width or x < 0 :
  415.     #         ConnectingRectangle.img_height / a
  416.            
  417.        
  418.        
  419.     # def horizontal_up(a,b):
  420.     #     pass
  421.  
  422.    
  423.    
  424.    
  425.    
  426.         # def extreme_values_ver_edges_up(a, b):
  427.     #     y_max = ConnectingRectangle.img_width * a + b
  428.     #     if y_max > ConnectingRectangle.img_height:
  429.     #         x_max = (ConnectingRectangle.img_height - b) /a
  430.     #         return x_max, ConnectingRectangle.img_height
  431.     #     else:
  432.     #         return ConnectingRectangle.img_width ,y_max
  433.    
  434.     # def extreme_values_ver_edges_down(a,b):
  435.     #     if b> 0 :
  436.     #         return 0, b
  437.     #     else:
  438.     #         x_min = -b / a
  439.     #         return x_min, 0
  440.