dan-masek

Untitled

May 30th, 2021 (edited)
447
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.14 KB | None | 0 0
  1. import functools
  2. import cv2
  3. import numpy as np
  4.  
  5. # ============================================================================
  6.  
  7. def determine_threshold(image):
  8.     window_main = "Determine Threshold"
  9.     cv2.namedWindow(window_main)
  10.  
  11.     result = { 'threshold' : 127 , 'mask' : None }
  12.     def on_trackbar_threshold(threshold_value):
  13.         gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  14.         _, mask = cv2.threshold(gray, threshold_value, 255, cv2.THRESH_BINARY_INV)
  15.        
  16.         display_image = np.hstack([image
  17.             , cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
  18.             , cv2.bitwise_and(image, image, mask=mask)
  19.         ])
  20.         cv2.imshow(window_main, display_image)
  21.        
  22.         result['threshold'] = threshold_value
  23.         result['mask'] = mask
  24.  
  25.     trackbar_thresh = "Threshold"
  26.     on_trackbar_threshold(result['threshold'])
  27.     cv2.createTrackbar(trackbar_thresh, window_main, result['threshold'], 255, on_trackbar_threshold)
  28.     on_trackbar_threshold(cv2.getTrackbarPos(trackbar_thresh, window_main))
  29.    
  30.     cv2.waitKey(0)
  31.     cv2.destroyWindow(window_main)
  32.     return result
  33.  
  34. # ============================================================================
  35.  
  36. def extract_clean_tile(image, mask, background_color):
  37.     window_main = "Extract Clean Tile"
  38.     cv2.namedWindow(window_main)
  39.  
  40.     contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  41.     sorted_contours = sorted(contours, key=lambda x: cv2.contourArea(x), reverse=True)
  42.     contour = sorted_contours[0]
  43.  
  44.     masked_image = cv2.bitwise_and(image, image, mask=mask) # Cache for display
  45.    
  46.     result = { 'tile' : None, 'mask' : None }
  47.     def on_trackbar_outline(scale):
  48.         approx_contour = cv2.approxPolyDP(contour, (scale / 20.0), True)
  49.         x, y, w, h = cv2.boundingRect(approx_contour)
  50.         PAD_X, PAD_Y = 8, 8
  51.         tx, ty, tw, th = x - PAD_X, y - PAD_Y , w + PAD_X * 2, h + PAD_Y * 2
  52.        
  53.         output_image_a = masked_image.copy()
  54.         cv2.drawContours(output_image_a, [contour], -1, (0,0,255), 1)
  55.        
  56.         cleaned_image = image.copy()
  57.         cv2.drawContours(cleaned_image, [approx_contour], -1, background_color, 3, cv2.LINE_AA)
  58.        
  59.         cleaned_mask = np.zeros_like(mask)
  60.         cv2.drawContours(cleaned_mask, [approx_contour], -1, (255,255,255), -1)
  61.         cleaned_masked_image = cv2.bitwise_and(cleaned_image, cleaned_image, mask=cleaned_mask)
  62.        
  63.         output_image_b = cleaned_masked_image.copy()
  64.         cv2.rectangle(output_image_b, (x - 1, y - 1), (x + w, y + h), (0, 191,191), 1)
  65.        
  66.         display_image = np.hstack([masked_image, output_image_a, output_image_b])
  67.         cv2.imshow(window_main, display_image)
  68.        
  69.         result['tile'] = cleaned_masked_image[y:y+h,x:x+w]
  70.         result['mask'] = cleaned_mask[y:y+h,x:x+w]
  71.  
  72.     trackbar_outline = "Approx."
  73.     on_trackbar_outline(0)
  74.     cv2.createTrackbar(trackbar_outline, window_main, 50, 200, on_trackbar_outline)
  75.     on_trackbar_outline(cv2.getTrackbarPos(trackbar_outline, window_main))
  76.  
  77.     cv2.waitKey(0)
  78.     cv2.destroyWindow(window_main)
  79.     return result
  80.  
  81. # ============================================================================
  82.  
  83. # NB: expects BGR tile
  84. def tile_pattern(tile, mask, rows, cols, background_color):
  85.     window_main = "Tile Pattern"
  86.     cv2.namedWindow(window_main)
  87.    
  88.     trackbar_csx, trackbar_csy, trackbar_rsx, trackbar_rsy = "col_step_x", "col_step_y", "row_step_x", "row_step_y"
  89.    
  90.     tile_height, tile_width = tile.shape[:2]
  91.     context = { trackbar_csx : tile_width
  92.         , trackbar_csy : 0
  93.         , trackbar_rsx : 0
  94.         , trackbar_rsy : tile_height
  95.     }
  96.    
  97.     def update_display():
  98.         col_step_x, col_step_y = context[trackbar_csx], context[trackbar_csy]
  99.         row_step_x, row_step_y = context[trackbar_rsx], context[trackbar_rsy]
  100.         #canvas_height = tile_height + row_step_y * (rows - 1) + col_step_y * (cols - 1)
  101.         #canvas_width = tile_width + col_step_x * (cols - 1) + row_step_x * (rows - 1)
  102.         canvas_height, canvas_width = tile_height * (rows + 1), tile_width * (cols + 1)
  103.         canvas = np.zeros((canvas_height, canvas_width, 3),  np.uint8)
  104.         canvas = canvas + np.uint8(background_color)
  105.  
  106.         output_mask = np.repeat((mask != 0)[:, :, np.newaxis], 3, axis=2)
  107.  
  108.         start_pos_x, start_pos_y = 0, 0
  109.         for x in range(rows):
  110.             pos_x, pos_y = start_pos_x, start_pos_y
  111.             for y in range(cols):
  112.                 dest = canvas[pos_y:pos_y+tile_height, pos_x:pos_x+tile_width]
  113.                 np.putmask(dest, output_mask, tile)
  114.                 pos_x, pos_y = pos_x + row_step_x, pos_y + row_step_y
  115.                 if pos_x > start_pos_x + tile_width:
  116.                     pos_x -= tile_width
  117.             start_pos_x, start_pos_y = start_pos_x + col_step_x, start_pos_y + col_step_y
  118.             if start_pos_y > tile_height:
  119.                 start_pos_y -= tile_height
  120.         cv2.imshow(window_main, canvas)
  121.        
  122.     def on_trackbar_step(scale, target):
  123.         context[target] = scale
  124.         update_display()
  125.  
  126.     update_display()
  127.    
  128.     cv2.createTrackbar(trackbar_csx, window_main, context[trackbar_csx], tile_width
  129.         , functools.partial(on_trackbar_step, target=trackbar_csx))
  130.     cv2.createTrackbar(trackbar_csy, window_main, context[trackbar_csy], tile_height
  131.         , functools.partial(on_trackbar_step, target=trackbar_csy))
  132.     cv2.createTrackbar(trackbar_rsx, window_main, context[trackbar_rsx], tile_width
  133.         , functools.partial(on_trackbar_step, target=trackbar_rsx))
  134.     cv2.createTrackbar(trackbar_rsy, window_main, context[trackbar_rsy], tile_height
  135.         , functools.partial(on_trackbar_step, target=trackbar_rsy))
  136.  
  137.     cv2.waitKey(0)
  138.     cv2.destroyWindow(window_main)
  139.  
  140. # ============================================================================
  141.  
  142. tile_image = cv2.imread('tile05.png')
  143. BACKGROUND_COLOR = (0, 0, 0)
  144.  
  145. thresh_result = determine_threshold(tile_image)
  146.  
  147. tile_result = extract_clean_tile(tile_image, thresh_result['mask'], BACKGROUND_COLOR)
  148.  
  149. tile_pattern(tile_result['tile'], tile_result['mask'], 3, 3, BACKGROUND_COLOR)
  150.  
  151.  
Add Comment
Please, Sign In to add comment