Advertisement
Guest User

Untitled

a guest
Jul 18th, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 16.23 KB | None | 0 0
  1. import cv2
  2. import matplotlib.pyplot as plt
  3. import numpy as np
  4. from mpl_toolkits.mplot3d import Axes3D
  5. from matplotlib import cm
  6. from matplotlib.ticker import LinearLocator, FormatStrFormatter
  7. from math import factorial
  8. from collections import Counter
  9. from sklearn.cluster import AffinityPropagation
  10. from itertools import count
  11.  
  12. img_1 = cv2.imread('E:/PythonProjects/ComponentProcessing1.0/1.jpg')
  13. img_2 = cv2.imread('E:/PythonProjects/ComponentProcessing1.0/2.jpg')
  14. img_3 = cv2.imread('E:/PythonProjects/ComponentProcessing1.0/3.jpg')
  15. img_4 = cv2.imread('E:/PythonProjects/ComponentProcessing1.0/4.jpg')
  16. img_5 = cv2.imread('E:/PythonProjects/ComponentProcessing1.0/5.jpg')
  17. img_6 = cv2.imread('E:/PythonProjects/ComponentProcessing1.0/6.jpg')
  18. img_7 = cv2.imread('E:/PythonProjects/ComponentProcessing1.0/7.jpg')
  19. img_8 = cv2.imread('E:/PythonProjects/ComponentProcessing1.0/8.jpg')
  20. img_9 = cv2.imread('E:/PythonProjects/ComponentProcessing1.0/9.jpg')
  21. img_10 = cv2.imread('E:/PythonProjects/ComponentProcessing1.0/10.jpg')
  22. img_11 = cv2.imread('E:/PythonProjects/ComponentProcessing1.0/1_ECU.jpg')
  23. img_12 = cv2.imread('E:/PythonProjects/ComponentProcessing1.0/2_ECU.jpg')
  24. img_13 = cv2.imread('E:/PythonProjects/ComponentProcessing1.0/3_ECU.jpg')
  25.  
  26.  
  27. def show_img(img):
  28.     plot = plt.imshow(img)
  29.     plt.set_cmap('bone')
  30.     plt.show()
  31.  
  32.  
  33. def convert_to_LAB(img):
  34.     """ Step 1: convert to LAB color-space
  35.        Argumentation: It enable to extract L factor which stands for luminance
  36.        Input: BGR image
  37.        Output: L channel """
  38.     l, a, b = cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2Lab))
  39.     return l
  40.  
  41.  
  42. def purity_extraction(img):
  43.     b, g, r = cv2.split(img)
  44.     s = (1 - np.divide(np.minimum.reduce([b, g, r]), np.maximum.reduce([b, g, r]))) * 255
  45.     nans = np.isnan(s)
  46.     s[nans] = 255
  47.     return s.astype(np.uint8, copy=False)
  48.  
  49.  
  50. def stripe_over_axis(img, axis: int, axis_coord: int):
  51.     return img[:, axis_coord] if axis else img[axis_coord, :]
  52.  
  53.  
  54. def std_dev_summary_over_axis(img, axis: int):
  55.     return np.std(img, axis=axis)
  56.  
  57.  
  58. def std_dev_over_axis_with_kernel(img, axis: int, axis_coord: int, kernel_size: int):
  59.     stripe = stripe_over_axis(img, axis, axis_coord)
  60.     stripe_divided = np.zeros((img.shape[not axis]-kernel_size+1, kernel_size))
  61.     for i in range(img.shape[not axis] - kernel_size + 1):
  62.         stripe_divided[i] = stripe[i:kernel_size+i]
  63.     return np.std(stripe_divided, axis=1)
  64.  
  65.  
  66. def plot_arrays(img_original, img_lab, *arrays):
  67.     titles = ['img original', 'img lab', 'std dev over columns', 'std dev over rows',
  68.               'std dev over columns kernel', 'std dev over rows kernel']
  69.     plt.figure(1)
  70.  
  71.     def mark_img(img, position: int, title_idx: int):
  72.         plt.subplot(position)
  73.         plt.imshow(img)
  74.         plt.set_cmap('bone')
  75.         plt.title(titles[title_idx])
  76.  
  77.     grid_size = len(arrays)*50 + 100 + 20
  78.     mark_img(img_original, grid_size+1, 0)
  79.     mark_img(img_lab, grid_size + 2, 1)
  80.     for idx, arr in enumerate(arrays):
  81.         plt.subplot(grid_size + 3 + idx)
  82.         plt.plot(np.arange(arr.size), arr)
  83.         plt.title(titles[2+idx])
  84.     plt.show()
  85.  
  86.  
  87. def create_std_dev_grid(img, axis: int, kernel_size: int):
  88.     """ Step 2: Return mask which represents standard deviation of color, calculated within specified axis with
  89.        kernel of given size.
  90.        Input: img: L channel of image
  91.        Output: np.ndarray which """
  92.     matrix_dim = (img.shape[not axis] - int(2 * (kernel_size - 1) / 2))
  93.     points = np.zeros((img.shape[0], matrix_dim)) if not axis else np.zeros((matrix_dim, img.shape[1]))
  94.     for i in range(img.shape[axis]):
  95.         if axis:
  96.             points[:, i] = std_dev_over_axis_with_kernel(img, axis, i, kernel_size)
  97.         else:
  98.             points[i] = std_dev_over_axis_with_kernel(img, axis, i, kernel_size)
  99.     return points
  100.  
  101.  
  102. def normalize_matrix(std_dev_matrix: np.ndarray):
  103.     """ Step 2b: """
  104.     return std_dev_matrix/np.max(std_dev_matrix)
  105.  
  106.  
  107. def summarize_std_dev(img, kernel_size: int):
  108.     """ Step 2: Function is controller for create_std_dev_grid function, because create_std_dev_grid is axis dependent
  109.        and what we need is information both from 0 and 1 axis. It also convolve extracted results.
  110.        TODO: set operator (current is multiplication as parameter to method)
  111.        Argumentation: Simplifying code
  112.        Input: img - image in L channel (from LAB colorspace), kernel_size - kernel size that will be used within
  113.        create_std_dev_grid.
  114.        Output: np.ndarray which is convolution of results over axis.
  115.        """
  116.     std_over_rows = normalize_matrix(create_std_dev_grid(img, 0, kernel_size))
  117.     std_over_columns = normalize_matrix(create_std_dev_grid(img, 1, kernel_size))
  118.     dim_diff = int((std_over_columns.shape[1] - std_over_rows.shape[1])/2)
  119.     return std_over_rows[dim_diff:-dim_diff, :] * std_over_columns[:, dim_diff:-dim_diff], dim_diff
  120.     # return np.maximum(std_over_rows[dim_diff:-dim_diff, :], std_over_columns[:, dim_diff:-dim_diff]), dim_diff
  121.  
  122.  
  123. def plot_matrix(points: np.ndarray):
  124.     X = np.arange(points.shape[1])
  125.     Y = np.arange(points.shape[0])
  126.     X, Y = np.meshgrid(X, Y)
  127.     fig = plt.figure()
  128.     ax = fig.gca(projection='3d')
  129.     surf = ax.plot_surface(X, Y, points, cmap=cm.coolwarm,
  130.                            linewidth=0, antialiased=False)
  131.     # Customize the z axis.
  132.     ax.set_zlim(-0.1, 1.2)
  133.     ax.zaxis.set_major_locator(LinearLocator(10))
  134.     ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
  135.     # Set labels for axes.
  136.     ax.set_xlabel('X')
  137.     ax.set_ylabel('Y')
  138.     ax.set_zlabel('Z')
  139.     # Add a color bar which maps values to colors.
  140.     fig.colorbar(surf, shrink=0.5, aspect=5)
  141.     plt.show()
  142.  
  143.  
  144. def select_extended_std_dev_matrix(original_img, summarized_std_dev: np.ndarray, offset: int, thresh: float):
  145.     extended_std_dev_matrix_shape = (summarized_std_dev.shape[0] + 2*offset, summarized_std_dev.shape[1] + 2*offset)
  146.     extended_std_dev_matrix = np.zeros(extended_std_dev_matrix_shape)
  147.     extended_std_dev_matrix[offset:-offset, offset:-offset] = summarized_std_dev
  148.     mask = np.zeros(extended_std_dev_matrix.shape, np.uint8)
  149.     selected_points = np.where(extended_std_dev_matrix < thresh)
  150.     mask[selected_points] = 255
  151.     return cv2.bitwise_and(original_img, mask), mask
  152.    
  153.  
  154. def savitzky_golay(y, window_size, order, deriv=0, rate=1):
  155.     window_size = np.abs(np.int(window_size))
  156.     order = np.abs(np.int(order))
  157.     order_range = range(order+1)
  158.     half_window = (window_size -1) // 2
  159.     # precompute coefficients
  160.     b = np.mat([[k**i for i in order_range] for k in range(-half_window, half_window+1)])
  161.     m = np.linalg.pinv(b).A[deriv] * rate**deriv * factorial(deriv)
  162.     # pad the signal at the extremes with
  163.     # values taken from the signal itself
  164.     firstvals = y[0] - np.abs( y[1:half_window+1][::-1] - y[0] )
  165.     lastvals = y[-1] + np.abs(y[-half_window-1:-1][::-1] - y[-1])
  166.     y = np.concatenate((firstvals, y, lastvals))
  167.     return np.convolve(m[::-1], y, mode='valid')
  168.  
  169.  
  170. def smooth_iteratively(arr: np.ndarray, iterations: int):
  171.     new_arr = np.array(arr)
  172.     for _ in range(iterations):
  173.         new_arr = savitzky_golay(new_arr, 31, 3)
  174.     return new_arr
  175.  
  176.  
  177. def get_stripe(mask: np.ndarray, axis_coord: int, axis: int):
  178.     if axis:
  179.         # select row
  180.         return mask[axis_coord, :]
  181.     else:
  182.         # select column
  183.         return mask[:, axis_coord]
  184.  
  185.  
  186. def filter_points(mask_stripe: np.ndarray, points: np.ndarray):
  187.     filtered_points = {'black': [], 'white': []}
  188.     left_border = mask_stripe[0]
  189.  
  190.     def append_point(color: str, left_border: int, right_border: int):
  191.         filtered_points[color].append(np.array([left_border, right_border, right_border-left_border]))
  192.  
  193.     def stack_array(color: str):
  194.         return np.stack(filtered_points[color])
  195.  
  196.     def remove_noise(points: np.ndarray, minimal_length: int):
  197.         return points[np.where(points[:, 2] > minimal_length)]
  198.  
  199.     # for right_border in points[:-1]:
  200.     for right_border in points:
  201.         right_border += 1
  202.         if all(mask_stripe[left_border:right_border] == 255):
  203.             append_point('black', left_border, right_border)
  204.         else:
  205.             append_point('white', left_border, right_border)
  206.         left_border = right_border
  207.     black_points = stack_array('black')
  208.     white_points = stack_array('white')
  209.     return remove_noise(black_points, 20), remove_noise(white_points, 20)
  210.  
  211.  
  212. def get_mask_with_points(img, points: dict, axis:int, color_l = (0, 0, 255), color_r = (0, 255, 0)):
  213.     if len(img.shape) == 2:
  214.         img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
  215.     for k, v in points.items():
  216.         for r in v:
  217.             if not axis:
  218.                 cv2.circle(img, (k, r[0]), 2, color_l, 1)
  219.                 cv2.circle(img, (k, r[1]), 2, color_r, 1)
  220.             else:
  221.                 cv2.circle(img, (r[0], k), 2, color_l, 1)
  222.                 cv2.circle(img, (r[1], k), 2, color_r, 1)
  223.     return img
  224.  
  225.  
  226. def get_mask_from_dict(img_shape: tuple, points: dict, axis: int):
  227.     mask = np.zeros(img_shape)
  228.     for k, v in points.items():
  229.         for r in v:
  230.             if not axis:
  231.                 mask[k, r[0]] = 255
  232.                 mask[k, r[1]] = 255
  233.             else:
  234.                 mask[r[0], k] = 255
  235.                 mask[r[1], k] = 255
  236.     return mask
  237.  
  238.  
  239. def create_counters(mask: np.ndarray, axis: int):
  240.     number_of_points = 200
  241.  
  242.     white, black = {}, {}
  243.     # sample_points = np.random.randint(0, mask.shape[axis], (number_of_points,))
  244.     sample_points = np.random.choice(mask.shape[not axis], size=number_of_points, replace=False)
  245.     for axis_coord in sample_points:
  246.         stripe = get_stripe(mask, axis_coord, axis)
  247.         value_changes_idx = np.where(stripe[:-1] != stripe[1:])[0]
  248.         if value_changes_idx.size > 0:
  249.             filtered_points_black, filtered_points_white = filter_points(stripe, value_changes_idx)
  250.             white[axis_coord] = filtered_points_white
  251.             black[axis_coord] = filtered_points_black
  252.  
  253.     # black, white = np.vstack(tuple(black)), np.vstack(tuple(white))
  254.     return white, black
  255.  
  256.  
  257. def stack_from_dict(points: dict):
  258.     number_of_rows = 0
  259.     for _, v in points.items():
  260.         number_of_rows += v.shape[0]
  261.     stacked = np.zeros((number_of_rows, 3))
  262.     idx = 0
  263.     for _, v in points.items():
  264.         stacked[idx: idx + v.shape[0]] = v
  265.         idx += v.shape[0]
  266.     return stacked
  267.  
  268.  
  269. def find_lines(points: dict, axis: int):
  270.     points = stack_from_dict(points)[:, axis].reshape(-1, 1)
  271.     aff_propagation = AffinityPropagation(max_iter=280, copy=False, convergence_iter=5).fit(points)
  272.     return aff_propagation.labels_, aff_propagation.cluster_centers_
  273.  
  274.  
  275. def find_lines_kernel(mask: np.ndarray, kernel_size: int, axis: int):
  276.     left_border = 0
  277.     # nonzero_vals = np.zeros((1+int((mask.shape[not axis] - kernel_size)/2), 2))
  278.     step = int(kernel_size/2)
  279.     nonzero_vals = np.zeros((int(mask.shape[not axis]/step), 2))
  280.     for i, right_border in zip(count(0), range(kernel_size, mask.shape[axis], step)):
  281.         if axis == 0:
  282.             # nonzero_vals.append(np.count_nonzero(mask[left_border:right_border, :]))
  283.             nonzero_vals[i, :] = np.array([np.count_nonzero(mask[left_border:right_border, :]),
  284.                                            int((left_border+right_border)/2)])
  285.         else:
  286.             # nonzero_vals.append(np.count_nonzero(mask[:, left_border:right_border]))
  287.             nonzero_vals[i, :] = np.array([np.count_nonzero(mask[:, left_border:right_border]),
  288.                                            int((left_border + right_border) / 2)])
  289.         left_border += int(kernel_size/2)
  290.     return nonzero_vals
  291.  
  292.  
  293. def select_pin_areas_from_mask(mask: np.ndarray):
  294.     sum_over_columns = np.sum(mask, axis=1)
  295.     sum_smoothed = smooth_iteratively(sum_over_columns, 5)
  296.     plt.subplot(221)
  297.     plt.plot(np.arange(sum_smoothed.size), sum_smoothed)
  298.     plt.subplot(222)
  299.     plt.plot(np.arange(sum_over_columns.size), sum_over_columns)
  300.     plt.subplot(223)
  301.     plt.imshow(mask)
  302.     plt.show()
  303.  
  304.  
  305. def get_two_peaks(arr: np.ndarray):
  306.  
  307.     def get_idx(arr: np.ndarray):
  308.         return np.argpartition(arr[:, 0], -1)[-1:]
  309.  
  310.     cut_point = int(arr.shape[0]/2)
  311.     idx1 = get_idx(arr[0:cut_point, :])
  312.     idx2 = get_idx(arr[cut_point:, :])
  313.     return arr[idx1, 1], arr[idx2+cut_point, 1]
  314.  
  315.  
  316.  
  317. img = img_12
  318. img_lab = convert_to_LAB(img)
  319. img_purity = purity_extraction(img)
  320.  
  321. # plot_arrays(img,
  322. #             img_lab,
  323. #             std_dev_summary_over_axis(img_lab, 0),
  324. #             std_dev_summary_over_axis(img_lab, 1),
  325. #             std_dev_over_axis_with_kernel(img_lab, 0, 160, 41),
  326. #             std_dev_over_axis_with_kernel(img_lab, 1, 480, 41))
  327.  
  328. # plot3D_cut_overview(img_lab, 41)
  329.  
  330. summarized_std_dev, offset = summarize_std_dev(img_lab, 31)
  331. masked_img, mask = select_extended_std_dev_matrix(img_lab, summarized_std_dev, offset, 0.2)
  332. plot_matrix(summarized_std_dev)
  333. show_img(np.hstack((img_lab, masked_img)))
  334. show_img(mask)
  335. ## select_pin_areas_from_mask(mask)
  336.  
  337. axis = 0
  338. w_x, b_x = create_counters(mask, axis)
  339. # img_with_mask_black_x = get_mask_with_points(img_lab, w_x, axis)
  340. # img_with_both_masks_x = get_mask_with_points(img_with_mask_black_x, b_x, axis, color_l=(255, 255, 0), color_r=(0, 255, 255))
  341.  
  342. axis = 1
  343. w_y, b_y = create_counters(mask, axis)
  344. # img_with_mask_black_y = get_mask_with_points(img_lab, w_y, axis)
  345. # img_with_both_masks_y = get_mask_with_points(img_with_mask_black_y, b_y, axis, color_l=(255, 255, 0), color_r=(0, 255, 255))
  346.  
  347. # show_img(np.hstack((img_with_both_masks_x, img_with_both_masks_y)))
  348.  
  349.  
  350. # labels, centers = find_lines(w_x, 0)
  351. # counter = Counter(labels).most_common(1)
  352. # most_common_x = centers[counter[0][0]]
  353. # cv2.line(img_with_mask_black_y, (most_common_x, 0), (most_common_x, img_with_both_masks_y.shape[0]), (255, 0, 170), 2)
  354. # show_img(img_with_mask_black_y)
  355.  
  356.  
  357. mask_x_wx = get_mask_from_dict(img_lab.shape, w_x, 1)
  358. mask_x_wy = get_mask_from_dict(img_lab.shape, b_x, 1)
  359. mask_y_wx = get_mask_from_dict(img_lab.shape, w_y, 0)
  360. mask_y_wy = get_mask_from_dict(img_lab.shape, b_y, 0)
  361.  
  362. mask_f = cv2.bitwise_or(mask_x_wx, mask_x_wy)
  363. mask_f = cv2.bitwise_or(mask_y_wx, mask_f)
  364. mask_f = cv2.bitwise_or(mask_y_wy, mask_f)
  365. show_img(mask_f)
  366. nonzero_rows = find_lines_kernel(mask_f, 15, 0)
  367. nonzero_cols = find_lines_kernel(mask_f, 15, 1)
  368.  
  369. vertical_line_1, vertical_line_2 = get_two_peaks(nonzero_rows)
  370. horizontal_line_1, horizontal_line_2 = get_two_peaks(nonzero_cols)
  371.  
  372. # img_colored = cv2.cvtColor(np.array(mask_f), cv2.COLOR_GRAY2BGR)
  373. cv2.line(mask_f, (int(horizontal_line_1), 0), (int(horizontal_line_1), mask_f.shape[0]), (127, 127, 0), 5)
  374. cv2.line(mask_f, (int(horizontal_line_2), 0), (int(horizontal_line_2), mask_f.shape[0]), (127, 127, 0), 5)
  375. cv2.line(mask_f, (0, int(vertical_line_1)), (mask_f.shape[1], int(vertical_line_1)), (250, 127, 127), 5)
  376. cv2.line(mask_f, (0, int(vertical_line_2)), (mask_f.shape[1], int(vertical_line_2)), (250, 127, 127), 5)
  377. show_img(mask_f)
  378.  
  379. plt.subplot(121)
  380. plt.plot(nonzero_rows[:, 0])
  381. plt.subplot(122)
  382. plt.plot(nonzero_cols[:, 0])
  383. plt.show()
  384.  
  385. '''TODO: uzaleznic miare od najmniejszej odleglosci miedzy kolejnymi punktami w wycinku
  386.   (proba znalezienia prostej najlepiej pasujacej do wycinka i stosunek lba punktow/odl od prostej)
  387.   TODO: uzaleznic rozmiar jadra od rozmiaru obrazka'''
  388.  
  389.  
  390.  
  391. #######################################################################################
  392.  
  393.  
  394. import numpy as np
  395. from sklearn import linear_model
  396. import matplotlib.pyplot as plt
  397. import cv2
  398.  
  399. def show_img(img):
  400.     plot = plt.imshow(img)
  401.     plt.set_cmap('bone')
  402.     plt.show()
  403.  
  404.  
  405. mtrx = np.zeros((40, 700))
  406. amount_of_points = 200
  407. points_y = np.random.randint(0, 40, amount_of_points)
  408. points_x = np.random.randint(0, 700, amount_of_points)
  409. mtrx[points_y, points_x] = 255
  410.  
  411.  
  412. non_zero_idx = np.flipud(np.vstack(np.where(mtrx != 0))).T
  413.  
  414.  
  415. ransac = linear_model.RANSACRegressor()
  416. ransac.fit(non_zero_idx[:, 0].reshape(-1, 1), non_zero_idx[:, 1])
  417.  
  418. line_x = np.arange(0, 700)[:, np.newaxis].astype(np.int)
  419. line_y = ransac.predict(line_x).astype(np.int)
  420.  
  421. img_colored = cv2.cvtColor(mtrx.astype(np.uint8), cv2.COLOR_GRAY2BGR)
  422. cv2.line(img_colored, (line_x[0], line_y[0]), (line_x[-1], line_y[-1]), (255, 255, 0), 1)
  423.  
  424. show_img(img_colored)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement