class VariableHousingCam1CropDInnerRing: INNER_CIRCLE_RAD = 463 INNER_CIRCLE_CENTER_COORD = Coordinate(1235, 1029) OUTER_CIRCLE_RAD = 645 OUTER_CIRCLE_CENTER_COORD = Coordinate(1254, 980) RING_SMALL_RAD = 401 ANGLE = 60
class VariableHousingCam1CropDRing: INNER_CIRCLE_RAD = 463 INNER_CIRCLE_CENTER_COORD = Coordinate(1235, 1029) OUTER_CIRCLE_RAD = 808 OUTER_CIRCLE_CENTER_COORD = Coordinate(1232, 993) RING_SMALL_RAD = 430 ANGLE = 60
def crop(self, bbox_list: list, angle_list: list, boundary_circle_center_coord: Coordinate, boundary_circle_rad: int): """ @TODO 이 부분 뺄 것 """ circle_crop_helper = CircleCropHelper(img_object=self.img_object, center_coord=Coordinate( 1205, 1062), rad=757) circle_crop_helper.crop_circle(inverse=True) outer_circle_img_object = circle_crop_helper.cropped_img_object rectangle_crop_helper = RectangleCropHelper( img_object=outer_circle_img_object) rectangle_img_list = list() for bbox, angle in zip(bbox_list, angle_list): bbox: BoundingBox rectangle_crop_helper.crop_rectangle(bbox=bbox) cropped_img_object = rectangle_crop_helper.cropped_img_object # Checking Defect for defect in self.defect_list: defect: Defect # Crop D 에서 defect 가 있을 때 if defect.is_defect_in_cropped_img( img_center_coord=boundary_circle_center_coord, margin_min=boundary_circle_rad, margin_max=2200): if defect.is_defect_in_bounding_box(bbox=bbox): rectangle_crop_helper.relocate_defect( img_object=cropped_img_object, defect=defect) # Rotate with angle cropped_img_object_width = cropped_img_object.img.shape[1] cropped_img_object_height = cropped_img_object.img.shape[0] cropped_img_object_center_coord = Coordinate( x=cropped_img_object_width // 2, y=cropped_img_object_height // 2) rotate_cropped_img = cv2.warpAffine( cropped_img_object.img, cv2.getRotationMatrix2D(cropped_img_object_center_coord.value, angle, scale=1), (cropped_img_object_width, cropped_img_object_height)) cropped_img_object.img = rotate_cropped_img rectangle_img_list.append(cropped_img_object) return rectangle_img_list
def crop(self, bbox: BoundingBox, boundary_circle_center_coord: Coordinate, boundary_circle_rad: int): """ @TODO 이 부분 뺄 것 """ circle_crop_helper = CircleCropHelper(img_object=self.img_object, center_coord=Coordinate( 1205, 1062), rad=757) circle_crop_helper.crop_circle(inverse=True) outer_circle_img_object = circle_crop_helper.cropped_img_object rectangle_crop_helper = RectangleCropHelper( img_object=outer_circle_img_object) rectangle_img_list = list() rectangle_crop_helper.crop_rectangle(bbox=bbox) cropped_img_object = rectangle_crop_helper.cropped_img_object # Checking defect for defect in self.defect_list: defect: Defect # Crop C 에서 defect 가 있을 때 if defect.is_defect_in_cropped_img( img_center_coord=boundary_circle_center_coord, margin_min=boundary_circle_rad, margin_max=2200): if defect.is_defect_in_bounding_box(bbox=bbox): rectangle_crop_helper.relocate_defect( img_object=cropped_img_object, defect=defect) rectangle_img_list.append(cropped_img_object) return rectangle_img_list
class VariableHousingCam3CropCRectangleTopSide: BBOX_LIST = [ BoundingBox(x_st=386, x_ed=386 + 461, y_st=182, y_ed=182 + 492), BoundingBox(x_st=1561, x_ed=1561 + 461, y_st=182, y_ed=182 + 492) ] BOUNDARY_CIRCLE_CENTER_COORD = Coordinate(1205, 1062) BOUNDARY_CIRCLE_RAD = 757 FLIP_INDEX = 0
class VariableHousingCam4Grid1: FIRST_CROP_X_ST = 40 CROP_SIZE = 128 FIRST_CROP_Y_ST = 1579 CROP_EMPTY_SPACE_Y_GAP = 622 CROP_Y_GAP = (128 / 4 * 3) # crop size / 4 * 3 LEFT_UP_COORDINATE = Coordinate(x=40, y=0)
class VariableHousingCam1CropA: # BIG_RAD = 710 # SMALL_RAD = 641 # CENTER_COORD = Coordinate(1255, 987) BIG_RAD = 705 SMALL_RAD = 639 CENTER_COORD = Coordinate(1254, 980) ANGLE = 30
class VariableHousingCam1CropDOuterRectangleWithRing: BBOX_LIST = [ BoundingBox(x_st=1822, x_ed=1822 + 500, y_st=780, y_ed=780 + 500), BoundingBox(x_st=850, x_ed=850 + 500, y_st=1646, y_ed=1646 + 500), BoundingBox(x_st=72, x_ed=72 + 500, y_st=766, y_ed=766 + 500) ] ANGLE_LIST = [0, 90, 180] BOUNDARY_CIRCLE_CENTER_COORD = Coordinate(1250, 987) BOUNDARY_CIRCLE_RAD = 710
class VariableHousingCam3CropCRectangleWithRing: BBOX_LIST = [ BoundingBox(x_st=1842, x_ed=1842 + 476, y_st=824, y_ed=824 + 476), BoundingBox(x_st=1049, x_ed=1049 + 476, y_st=1707, y_ed=1707 + 476), BoundingBox(x_st=79, x_ed=79 + 476, y_st=831, y_ed=831 + 476) ] ANGLE_LIST = [0, 90, 180] BOUNDARY_CIRCLE_CENTER_COORD = Coordinate(1205, 1062) BOUNDARY_CIRCLE_RAD = 757
def get_area_with_coord(cls, coord: Coordinate): area_list = list() """ A """ crop_variable = c1p.CROP_A_VARIABLE if coord.is_in_margin(img_center_coord=crop_variable.CENTER_COORD, margin_min=crop_variable.SMALL_RAD, margin_max=crop_variable.BIG_RAD): area_list.append(c1p.CAM1_AREA.A) """ C """ crop_variable = c1p.CROP_C_ENTIRE_VARIABLE if coord.is_in_margin(img_center_coord=crop_variable.CENTER_COORD, margin_min=0, margin_max=crop_variable.RAD): area_list.append(c1p.CAM1_AREA.C) """ D_inner """ crop_variable = c1p.CROP_D_INNER_RING_VARIABLE # Crop C 바깥에 위치한 경우 _is_first_circle_outside = coord.is_in_margin( img_center_coord=crop_variable.INNER_CIRCLE_CENTER_COORD, margin_min=crop_variable.INNER_CIRCLE_RAD, margin_max=2000 # Temp ) # Crop D 외곽 반지름 안에 위치한 경우 _is_second_circle_inside = coord.is_in_margin( img_center_coord=crop_variable.OUTER_CIRCLE_CENTER_COORD, margin_min=1, # Temp margin_max=crop_variable.OUTER_CIRCLE_RAD) if _is_first_circle_outside and _is_second_circle_inside: area_list.append(c1p.CAM1_AREA.D_INNER) """ D_outer """ crop_variable = c1p.CROP_D_OUTER_ENTIRE_VARIABLE if coord.is_in_margin(img_center_coord=crop_variable.CENTER_COORD, margin_min=crop_variable.RAD, margin_max=2000): area_list.append(c1p.CAM1_AREA.D_OUTER) if area_list: return area_list[0] else: return None
def get_area_with_coord(cls, coord: Coordinate): area_list = list() """ A """ crop_variable = c3p.CROP_A_VARIABLE if coord.is_in_margin(img_center_coord=crop_variable.CENTER_COORD, margin_min=crop_variable.SMALL_RAD, margin_max=crop_variable.BIG_RAD): area_list.append(c3p.CAM3_AREA.A) """ C_inner_ring_inside """ crop_variable = c3p.CROP_C_INNER_RING_INSIDE_ENTIRE_VARIABLE if coord.is_in_margin(img_center_coord=crop_variable.CENTER_COORD, margin_min=0, margin_max=crop_variable.RAD): area_list.append(c3p.CAM3_AREA.C_INNER_RING_INSIDE) """ C_inner_ring_outside """ crop_variable = c3p.CROP_C_INNER_RING_OUTSIDE_ENTIRE_VARIABLE if coord.is_in_margin(img_center_coord=crop_variable.CENTER_COORD, margin_min=crop_variable.SMALL_RAD, margin_max=crop_variable.BIG_RAD + 100): # 안전하게 + 100 (경계선에 걸친 coord 존재) area_list.append(c3p.CAM3_AREA.C_INNER_RING_OUTSIDE) """ C_outer """ crop_variable = c3p.CROP_C_OUTER_ENTIRE_VARIABLE if coord.is_in_margin(img_center_coord=crop_variable.CENTER_COORD, margin_min=crop_variable.RAD, margin_max=2000): area_list.append(c3p.CAM3_AREA.C_OUTER) """ D """ crop_variable = c3p.CROP_D_RING_ENTIRE_VARIABLE if coord.is_in_margin( img_center_coord=crop_variable.CENTER_COORD, margin_min=crop_variable.SMALL_RAD - 100, # 안전하게 - 100 (경계선에 걸친 coord 존재) margin_max=crop_variable.BIG_RAD): area_list.append(c3p.CAM3_AREA.D) if area_list: return area_list[0] else: return None
class VariableHousingCam1CropDOuterRectangleTop: ENTIRE_X_ST = 598 ENTIRE_X_ED = 598 + 1184 ENTIRE_Y_ST = 132 ENTIRE_Y_ED = 132 + 368 BOUNDARY_CIRCLE_CENTER_COORD = Coordinate(1250, 987) BOUNDARY_CIRCLE_RAD = 710 FLIP_INDEX = 0 __HALF_X = (ENTIRE_X_ST + ENTIRE_X_ED) // 2 BBOX_LIST = [ BoundingBox(x_st=ENTIRE_X_ST, x_ed=__HALF_X, y_st=ENTIRE_Y_ST, y_ed=ENTIRE_Y_ED), BoundingBox(x_st=__HALF_X, x_ed=ENTIRE_X_ED, y_st=ENTIRE_Y_ST, y_ed=ENTIRE_Y_ED) ]
def crop(self, bbox_list: list, boundary_circle_center_coord: Coordinate, boundary_circle_rad: int, flip_index: int = 0): """ @TODO 이 부분 뺄 것 """ circle_crop_helper = CircleCropHelper(img_object=self.img_object, center_coord=Coordinate( 1205, 1062), rad=757) circle_crop_helper.crop_circle(inverse=True) outer_circle_img_object = circle_crop_helper.cropped_img_object rectangle_crop_helper = RectangleCropHelper( img_object=outer_circle_img_object) rectangle_img_list = list() for idx, bbox in enumerate(bbox_list): rectangle_crop_helper.crop_rectangle(bbox=bbox) cropped_img_object = rectangle_crop_helper.cropped_img_object # Checking defect for defect in self.defect_list: defect: Defect # Crop C 에서 defect 가 있을 때 if defect.is_defect_in_cropped_img( img_center_coord=boundary_circle_center_coord, margin_min=boundary_circle_rad, margin_max=2200): if defect.is_defect_in_bounding_box(bbox=bbox): rectangle_crop_helper.relocate_defect( img_object=cropped_img_object, defect=defect) # Flip the image if idx == flip_index: flipped_cropped_img = cv2.flip(cropped_img_object.img, 1) # 1 은 좌우 반전 cropped_img_object.img = flipped_cropped_img rectangle_img_list.append(cropped_img_object) return rectangle_img_list
def get_ring_mask(self, big_rad: int, small_rad: int): center_coord = Coordinate(big_rad, big_rad) frame_size = (big_rad * 2, big_rad * 2) mask_big = np.zeros(frame_size, dtype=np.uint8) mask_small = np.zeros(frame_size, dtype=np.uint8) cv2.circle(mask_big, center_coord.value, big_rad, (255, 255, 255), thickness=-1) cv2.circle(mask_small, center_coord.value, small_rad, (255, 255, 255), thickness=-1) return (mask_big - mask_small) / 255
class VariableHousingCam3CropCRectangleTopMiddle: ENTIRE_X_ST = 837 ENTIRE_X_ED = 837 + 736 ENTIRE_Y_ST = 304 ENTIRE_Y_ED = 304 + 95 __HALF_X = (ENTIRE_X_ST + ENTIRE_X_ED) // 2 BBOX_LIST = [ BoundingBox(x_st=ENTIRE_X_ST, x_ed=__HALF_X, y_st=ENTIRE_Y_ST, y_ed=ENTIRE_Y_ED), BoundingBox(x_st=__HALF_X, x_ed=ENTIRE_X_ED, y_st=ENTIRE_Y_ST, y_ed=ENTIRE_Y_ED) ] BOUNDARY_CIRCLE_CENTER_COORD = Coordinate(1205, 1062) BOUNDARY_CIRCLE_RAD = 757 FLIP_INDEX = 0
class VariableHousingCam3CropCRectangleTop: ENTIRE_X_ST = 386 ENTIRE_X_ED = 1561 + 461 ENTIRE_Y_ST = 182 ENTIRE_Y_ED = 182 + 492 __HALF_X = (ENTIRE_X_ST + ENTIRE_X_ED) // 2 BBOX_LIST = [ BoundingBox(x_st=ENTIRE_X_ST, x_ed=__HALF_X, y_st=ENTIRE_Y_ST, y_ed=ENTIRE_Y_ED), BoundingBox(x_st=__HALF_X, x_ed=ENTIRE_X_ED, y_st=ENTIRE_Y_ST, y_ed=ENTIRE_Y_ED) ] BOUNDARY_CIRCLE_CENTER_COORD = Coordinate(1205, 1062) BOUNDARY_CIRCLE_RAD = 757 FLIP_INDEX = 0
def get_candidate_coord_list(self, distance_margin_min, distance_margin_max, contour_size_margin_min, contour_size_margin_max, contour_area_margin_min, contour_area_margin_max): candidate_coord_list = list() for important_pixel_coord in self.important_pixel_coord_list: important_pixel_coord: Coordinate is_candidate = False best_distance = None best_contour = None if "A" in important_pixel_coord.area.name: is_candidate = True else: # 가장 가까운 contour 찾기 for contour in self.contour_list: contour: Contour distance = important_pixel_coord.get_distance( coord=contour.center) # Distance 예외 if not distance_margin_min <= distance < distance_margin_max: continue if best_distance is None or distance < best_distance: best_distance = distance best_contour = contour if best_contour: # Contour margin 측정 rect_pt_1, rect_pt_2, rect_pt_3, rect_pt_4 = best_contour.box_list rect_length_1 = Coordinate( rect_pt_1[1], rect_pt_1[0]).get_distance( Coordinate(rect_pt_2[1], rect_pt_2[0])) rect_length_2 = Coordinate( rect_pt_1[1], rect_pt_1[0]).get_distance( Coordinate(rect_pt_4[1], rect_pt_4[0])) # Ellipse 측정 # (x, y), (MA, ma), angle = best_contour.ellipse # ellipse_area = math.pi * MA * ma rect_area = rect_length_1 * rect_length_2 print(best_distance, rect_area, rect_length_1, rect_length_2) if contour_area_margin_min <= rect_area < contour_area_margin_max \ and contour_size_margin_min <= rect_length_1 < contour_size_margin_max \ and contour_size_margin_min <= rect_length_2 < contour_size_margin_max: is_candidate = True # Final if is_candidate: candidate_coord_list.append(important_pixel_coord) return candidate_coord_list
class VariableHousingCam1CropDOuterRingOutside: BIG_RAD = 825 SMALL_RAD = 782 CENTER_COORD = Coordinate(1249, 979) ANGLE = 15 INDEX_LIST = [0, 1, 13, 14, 15, 16, 17, 18, 22, 23]
class VariableHousingCam1CropDOuterRingInside: BIG_RAD = 782 SMALL_RAD = 705 CENTER_COORD = Coordinate(1249, 975) ANGLE = 30
class VariableHousingCam1CropDOuterEntire: RAD = 705 CENTER_COORD = Coordinate(1254, 980)
class VariableHousingCam1CropDOuterRing: BIG_RAD = 843 SMALL_RAD = 715 CENTER_COORD = Coordinate(1250, 987) ANGLE = 30 INDEX_LIST = [2, 4, 5, 6, 7, 8, 10]
class VariableHousingCam1CropCEntire: RAD = 463 CENTER_COORD = Coordinate(1235, 1029)
class VariableHousingCam1CropC: BIG_RAD = 463 SMALL_RAD = 103 CENTER_COORD = Coordinate(1235, 1029) ANGLE = 90
class VariableHousingCam1Grid13: LEFT_UP_COORDINATE = Coordinate(x=1791, y=949) BBOX_LIST = [ BoundingBox(x_st=1791, x_ed=1791 + 512, y_st=949, y_ed=949 + 512) ]
class VariableHousingCam1Grid15: LEFT_UP_COORDINATE = Coordinate(x=1125, y=1629) BBOX_LIST = [ BoundingBox(x_st=1125, x_ed=1125 + 512, y_st=1629, y_ed=1629 + 512) ]
class VariableHousingCam1Grid12: LEFT_UP_COORDINATE = Coordinate(x=1791, y=547) BBOX_LIST = [ BoundingBox(x_st=1791, x_ed=1791 + 512, y_st=547, y_ed=547 + 512) ]
class VariableHousingCam1Grid11: LEFT_UP_COORDINATE = Coordinate(x=27, y=993) BBOX_LIST = [ BoundingBox(x_st=27, x_ed=27 + 512, y_st=993, y_ed=993 + 512) ]
class VariableHousingCam1Grid9: LEFT_UP_COORDINATE = Coordinate(x=1459, y=1138) BBOX_LIST = [ BoundingBox(x_st=1459, x_ed=1459 + 512, y_st=1138, y_ed=1138 + 512) ]
class VariableHousingCam1Grid5: LEFT_UP_COORDINATE = Coordinate(x=965, y=644) BBOX_LIST = [ BoundingBox(x_st=965, x_ed=965 + 512, y_st=644, y_ed=644 + 512) ]
class VariableHousingCam1Grid6: LEFT_UP_COORDINATE = Coordinate(x=1459, y=644) BBOX_LIST = [ BoundingBox(x_st=1459, x_ed=1459 + 512, y_st=644, y_ed=644 + 512) ]