def _detect_protrusionlike(self, img, filled, holes): """Detect 'protrusion'-like salient regions Parameters ------ img: 2-dimensional numpy array with values 0/255 image to detect holes filled: 2-dimensional numpy array with values 0/255, optional precomputed filled image holes: 2-dimensional numpy array with values 0/255 The earlier detected holes Returns ------ protrusions: 2-dimensional numpy array with values 0/255 Image with all protrusions as foreground. """ # Calculate minimum area for connected components min_area = self.area_factor * img.size # Initalize protrusion image prots1 = np.zeros(img.shape, dtype='uint8') prots2 = np.zeros(img.shape, dtype='uint8') # Retrieve all connected components nccs, labels, stats, centroids = cv2.connectedComponentsWithStats( filled, connectivity=self.connectivity) for i in range(1, nccs): area = stats[i, cv2.CC_STAT_AREA] # For the significant CCs, perform tophat if area > min_area: ccimage = np.array(255 * (labels == i), dtype='uint8') wth = cv2.morphologyEx(ccimage, cv2.MORPH_TOPHAT, self.SE) prots1 += wth prots1_nonoise = self._remove_small_elements(prots1) # Now get indentations of significant holes nccs2, labels2, stats2, centroids2 = cv2.connectedComponentsWithStats( holes, connectivity=self.connectivity) for i in range(1, nccs2): area = stats2[i, cv2.CC_STAT_AREA] ccimage = np.array(255 * (labels2 == i), dtype='uint8') ccimage_filled = _fill_image(ccimage, self.connectivity) # For the significant CCs, perform tophat if area > min_area: bth = cv2.morphologyEx( ccimage_filled, cv2.MORPH_BLACKHAT, self.SE) prots2 += bth prots2_nonoise = self._remove_small_elements(prots2) prots = cv2.add(prots1_nonoise, prots2_nonoise) return prots
def get_corners_subpixel(filename): img = cv2.imread(filename) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # find Harris corners gray = np.float32(gray) dst = cv2.cornerHarris(gray, 2, 3, 0.04) dst = cv2.dilate(dst, None) ret, dst = cv2.threshold(dst, 0.01 * dst.max(), 255, 0) dst = np.uint8(dst) # find centroids ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst) # define the criteria to stop and refine the corners criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001) corners = cv2.cornerSubPix( gray, np.float32(centroids), (5, 5), (-1, -1), criteria) # Now draw them res = np.hstack((centroids, corners)) res = np.int0(res) img[res[:, 1], res[:, 0]] = [0, 0, 255] img[res[:, 3], res[:, 2]] = [0, 255, 0] cv2.imwrite(filename.replace('.jpg', '_corner_sub.jpg'), img)
def corner_detect(img): # gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = img # find Harris corners gray = np.float32(gray) dst = cv2.cornerHarris(gray, 2, 3, 0.04) dst = cv2.dilate(dst, None) ret, dst = cv2.threshold(dst, 0.01 * dst.max(), 255, 0) dst = np.uint8(dst) # find centroids ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst) # define the criteria to stop and refine the corners criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001) corners = cv2.cornerSubPix(gray, np.float32(centroids), (5, 5), (-1, -1), criteria) # Now draw them PIX = 1 res = np.hstack((centroids, corners)) res = np.int0(res) for w in range(-PIX, PIX): for ww in range(-PIX, PIX): try: img[res[:, 1] + w, res[:, 0] + ww] = 255 # [0, 0, 255] img[res[:, 3] + w, res[:, 2] + ww] = 0 # [0, 255, 0] except IndexError: # FIXME pass
def labeling(img, minsize, maxsize): hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, th = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY) ret, labels, stats, centroids = cv2.connectedComponentsWithStats(th) areas = [] for i in range(ret): if int(stats[i][4]) >= minsize: if int(stats[i][4]) <= maxsize: areas.append(i) sortareas = [] for i in areas: sortareas.append([int(stats[i][4]), i]) sortareas = sorted(sortareas, reverse = True) areanums = [sortareas[i][1] for i in range(len(sortareas))] centers = [] for i in areanums: x = int(centroids[i][0]) y = int(centroids[i][1]) centers.append([x, y]) return centers
def find_centroids(corners): radius = 100 maximum = corners.max() corners = cv2.threshold(corners, int(maximum*0.5), maximum, cv2.THRESH_BINARY)[1] corners = np.uint8(corners) temp = cv2.connectedComponentsWithStats(corners) return temp[3]
def ccv(src, tau=0, n=64): img = src.copy() row, col, channels = img.shape if not col == 300: aspect = 300.0//col img = cv2.resize(img, None, fx=aspect, fy=aspect, interpolation=cv2.INTER_CUBIC) row, col, channels = img.shape # blur img = cv2.GaussianBlur(img, (3, 3), 0) # quantize color img = quantize_color(img, n) bgr = cv2.split(img) #bgr = cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2HSV)) if tau == 0: tau = row*col * 0.1 alpha = np.zeros(n) beta = np.zeros(n) # labeling for i, ch in enumerate(bgr): ret, th = cv2.threshold(ch, 127, 255, 0) ret, labeled, stat, centroids = cv2.connectedComponentsWithStats(th, None, cv2.CC_STAT_AREA, None, connectivity=8) areas = [[v[4], label_idx] for label_idx, v in enumerate(stat)] coord = [[v[0], v[1]] for label_idx, v in enumerate(stat)] # Counting for a, c in zip(areas,coord): area_size = a[0] x, y = c[0], c[1] if (x < ch.shape[1]) and (y < ch.shape[0]): bin_idx = int(ch[y, x]//(256//n)) if area_size >= tau: alpha[bin_idx] = alpha[bin_idx] + area_size else: beta[bin_idx] = beta[bin_idx] + area_size return alpha, beta
def find_ccomp(im, *args, **kvargs): num, labels, stats, centroids = cv2.connectedComponentsWithStats(im, *args, **kvargs) stats_df = pd.DataFrame(stats, columns=['left', 'top', 'width', 'height', 'area']) stats_df['x'] = centroids[:,0] stats_df['y'] = centroids[:,1] return labels, stats_df
def cuentadedosesq(mascara): # Con la siguiente funcion se identifican todos los objetos que hay en una imagen binaria # En este caso se quieren identificar los objetos que hay en la imagen binaria que contiene el esqueleto de la mano. ret, labels, stats, centroids = cv2.connectedComponentsWithStats(mascara) # De los valores de retorno de la funcion anterior se usa stats, # stars es una matriz con 5 columnas (left,top,width,height,area) y un numero de filas en funcion del numero de objetos # que hay en la imagen. sizearea = stats[:, 4] # vector con todas las areas de los objetos de la imagen: cont=0 labelspeque=[] # Se pone como valores limites de area de los objetos 200<area<1000 # dichos valores se usan para eliminar los segmentos del esqueleto muy pequenos y muy grandes. # Se han obtenido despues de un estudio de diferentes manos y posiciones de las mismas. areamin=200 areamax=1000 for i in sizearea: if i > areamin: if i < areamax: cont=cont+1 #labelspeque dice los objetos con un area dentro del rango establecido labelspeque.append(cont) #cont devuelve el numero de dedos. return cont
def get_harris_corners(): filename = 'emptyboard.png' img = cv2.imread(filename) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = np.float32(gray) dst = cv2.cornerHarris(gray,2,3,0.04) dst = cv2.dilate(dst,None) ret, dst = cv2.threshold(dst,0.01*dst.max(),255,0) dst = np.uint8(dst) # find centroids ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst) # define the criteria to stop and refine the corners criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001) corners = cv2.cornerSubPix(gray,np.float32(centroids),(5,5),(-1,-1),criteria) #print and write to file print(corners) f = open('color1.txt', 'w') for item in corners: f.write(str(item[0]) + "\t" + str(item[1]) + "\n") # Now draw them res = np.hstack((centroids,corners)) res = np.int0(res) #img[res[:,1],res[:,0]]=[0,0,255] #RED img[res[:,3],res[:,2]] = [0,255,0] #GREEN cv2.imwrite('color1.png',img)
def get_mask(self, image=None): if image is None: image = self.domino_image self.show_image(image=image) gray_scene = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) _, thresh = cv2.threshold(gray_scene, 200, 255, cv2.THRESH_BINARY) self.show_image(image=thresh) kernel = np.ones((25,25),np.uint8) closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) ret, labels, stats, centroids = cv2.connectedComponentsWithStats(closed, connectivity=4) for i in range(2, ret): im = labels[labels==i] print im.shape # self.show_image(image = labels[labels==i]) print ret print labels print stats print centroids return closed
def make_panorama(original1,original2): matcher = cv2.BFMatcher(cv2.NORM_L2,False) matches = matcher.knnMatch(original1.des,original2.des,2) goodmatches = [] trainkeys = [] querykeys = [] maskArray = [] for i in matches: if i[0].distance < 500: if i[0].distance/i[1].distance < 0.8: print("\U0001F37A", end=' ') goodmatches.append(i[0]) querykeys.append((original1.kp[i[0].queryIdx].pt[0],original1.kp[i[0].queryIdx].pt[1])) trainkeys.append((original2.kp[i[0].trainIdx].pt[0],original2.kp[i[0].trainIdx].pt[1])) print("-----Calculating Homography-----") H, status = cv2.findHomography(np.array(trainkeys),np.array(querykeys),cv2.RANSAC, 5.0) print('-----finished to calculate-----') div = calcDst4(H, original2.image.shape) d = original1.resizeMat2(div) print(original1.image.shape) T_xy = [[1,0,-d[0]],[0,1,-d[1]],[0,0,1]] panorama = cv2.warpPerspective(original2.image,np.dot(T_xy,H),(original1.image.shape[1],original1.image.shape[0])) #panorama, mask = Write(panorama,original1) CommonMask, SrcMask= MakeMask(panorama, original1.image) label = cv2.connectedComponentsWithStats(CommonMask) center = np.delete(label[3], 0, 0) print(center[0]) blending = cv2.seamlessClone(original1.image, panorama, CommonMask, (int(center[0][0]),int(center[0][1])), cv2.NORMAL_CLONE) blending = Write2(blending, original1.image, SrcMask) cv2.imshow('blend',blending) print("--next--") return blending
def getGripperCenter(img): def getDistance(X, Y): dx = X[0] - Y[0] dy = X[1] - Y[1] return dx * dx + dy * dy hsvImg = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) lower_red_hue_range = cv2.inRange(img, (0, 0, 150), (100, 100, 255)) upper_red_hue_range = cv2.inRange(hsvImg, (160, 100, 50), (185, 255, 255)) red_hue_image = cv2.addWeighted(lower_red_hue_range, 1.0, upper_red_hue_range, 1.0, 0.0) redImg = red_hue_image.copy() lower_yel_hue_range = cv2.inRange(img, (0, 150, 0), (100, 255, 100)) upper_yel_hue_range = cv2.inRange(hsvImg, (20, 120, 0), (115, 255, 180)) yel_hue_image = cv2.addWeighted(lower_yel_hue_range, 1.0, upper_yel_hue_range, 1.0, 0.0) yelImg = yel_hue_image.copy() redImg = cv2.medianBlur(redImg, 5) yelImg = cv2.medianBlur(yelImg, 5) redImg = cv2.GaussianBlur(redImg, (9, 9), 0) yelImg = cv2.GaussianBlur(yelImg, (9, 9), 0) redOut = cv2.connectedComponentsWithStats(redImg, 4, cv2.CV_32S) cenRed = redOut[3] print (len(cenRed)) yelOut = cv2.connectedComponentsWithStats(yelImg, 4, cv2.CV_32S) cenYel = yelOut[3] print (len(cenYel)) minD = -1 result = (0, 0) for a in cenRed: for b in cenYel: d = getDistance(a, b) if (minD < 0 or d < minD): minD = d result = ((a[0] + b[0]) / 2, (a[1] + b[1]) / 2) print result return list(map(int, result))
def splitimage(image): dpmm = min(image.shape[0:2]) / DOCSIZE[0] sizethresh = SIZE_THRESH_MM * dpmm uprightimg = makeupright(image) grayimg = getgrayimage(uprightimg) # top line top = grayimg[0,:] sepx = [0,] ret, binimg = cv2.threshold(top,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(binimg) for i in range(1,nlabels): if stats[i,cv2.CC_STAT_AREA] >= sizethresh: sepx.append(centroids[i][1]) # left line left = grayimg[:,0] sepy = [0,] ret, binimg = cv2.threshold(left,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(binimg) for i in range(1,nlabels): if stats[i,cv2.CC_STAT_AREA] >= sizethresh: sepy.append(centroids[i][1]) # divide into images imgs = [] for iy in range(len(sepy)): for ix in range(len(sepx)): if iy == len(sepy) - 1: if ix == len(sepx) - 1: #right-bottom corner imgs.append(uprightimg[int(sepy[iy]):,int(sepx[ix]):]) else: #bottom end imgs.append(uprightimg[int(sepy[iy]):,int(sepx[ix]):int(sepx[ix+1])]) else: if ix == len(sepx) - 1: #right end imgs.append(uprightimg[int(sepy[iy]):int(sepy[iy+1]),int(sepx[ix]):]) else: #others imgs.append(uprightimg[int(sepy[iy]):int(sepy[iy+1]),int(sepx[ix]):int(sepx[ix+1])]) return imgs
def get_bounding_box(img): output = cv2.connectedComponentsWithStats(img_as_ubyte(img), 4, cv2.CV_32S) stats = output[2] box = ( stats[1][0], stats[1][1], stats[0][2] - (stats[1][0] + stats[1][2]), stats[0][3] - (stats[1][1] + stats[1][3]), ) return box
def detectText(img): mser = cv2.MSER_create() regions = mser.detectRegions(img, None) mask = np.zeros(img.shape, np.uint8) for points in regions: for point in points: mask.itemset(point[1],point[0],255) ''' smoothedInput = cv2.GaussianBlur(img, (7,7), math.sqrt(2)) edges = cv2.Canny(smoothedInput, 120, 120) MserAndCanny = mask&edges sobelx = cv2.Sobel(img,cv2.CV_64F,1,0) sobely = cv2.Sobel(img,cv2.CV_64F,0,1) gradAngle = cv2.phase(sobelx,sobely) MserAndCannyGrown = growEdges(MserAndCanny,gradAngle,2) MserAndCannyGrown = np.uint8(np.absolute(MserAndCannyGrown)) ''' se = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)) gradient = cv2.morphologyEx(mask, cv2.MORPH_GRADIENT, se) edgeEnhancedMserMask = (255 - gradient)&mask #display(edgeEnhancedMserMask) no,CC,stats,Cen = cv2.connectedComponentsWithStats(edgeEnhancedMserMask) new = CCAnalysis(CC,no,stats) #display(new) strokeWidths = swt.swtChenAltered(new) strokeWidths = np.uint8(np.absolute(strokeWidths)) #plt.imshow(strokeWidths, cmap='jet', interpolation='nearest');plt.show() newer = np.zeros((height,width),np.uint8) mask = np.zeros((height,width),np.uint8) no,CC,stats,Cen = cv2.connectedComponentsWithStats(new) for i in range(1,no): mask[::] = 0 Index = np.where(CC==i) mask[Index] = 255 if np.std(strokeWidths[Index])/np.mean(strokeWidths[Index])>0.35: continue newer = newer|mask se1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(50,50)) se2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(2,2)) im1 = cv2.morphologyEx(newer, cv2.MORPH_CLOSE, se1) im2 = cv2.morphologyEx(im1, cv2.MORPH_OPEN, se2) return im2
def select_region_closest_to_center(mask, original, scale=1.0): mask = crop_to_center(mask, scale) original = crop_to_center(original, scale) output = cv2.connectedComponentsWithStats(img_as_ubyte(mask), 4, cv2.CV_32S) regions = output[1] center_id, coord, distance, found = centermost_foreground_id(regions) region = regions == center_id kernel = np.ones((9, 9), np.uint8) region = cv2.dilate(img_as_ubyte(region), kernel, iterations=2) output = cv2.connectedComponentsWithStats(img_as_ubyte(region), 4, cv2.CV_32S) stats = output[2] padding = 25 top = stats[1][1] - padding left = stats[1][0] - padding width = stats[1][2] + (padding * 2) height = stats[1][3] + (padding * 2) bottom = top + height right = left + width crop_box = ( top, bottom, left, right, ) region = region[ top:bottom, left:right ] original = original[ top:bottom, left:right ] return region, original, crop_box
def _connect_components_analysis(image): """ :param image: :return: """ if len(image.shape) == 3: gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) else: gray_image = image return cv2.connectedComponentsWithStats(gray_image, connectivity=8, ltype=cv2.CV_32S)
def binarize(img): img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(img_gray, (5, 5), 0) #return cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) #res_image = cv2.threshold(blur, 0, 1,cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1] res_image = cv2.threshold(blur, 60, 1,cv2.THRESH_BINARY)[1] kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(10,10)) res_image = cv2.morphologyEx(res_image, cv2.MORPH_OPEN, kernel) #res_image = cv2.morphologyEx(res_image, cv2.MORPH_CLOSE, kernel) ret, labels, stats, centroids = cv2.connectedComponentsWithStats(res_image, 8, cv2.CV_32S) i_component = np.argmax(stats[1:, cv2.CC_STAT_AREA]) + 1 return (labels == i_component).astype(np.uint8)
def _remove_small_elements( self, elements, connectivity=None, remove_border_elements=True, visualize=False): """Remove elements (Connected Components) that are smaller then a given threshold Parameters ------ elements : numpy array binary image with elements connectivity: int, optional What connectivity to use to define CCs remove_border_elements: bool, optional Also remove elements that are attached to the border visualize: bool, optional option for visualizing the process Returns ------ result : numpy array Binary image with all elements larger then lam """ if connectivity is None: connectivity = self.connectivity result = elements.copy() nr_elements, labels, stats, _ = cv2.connectedComponentsWithStats( elements, connectivity=connectivity) leftborder = 0 rightborder = elements.shape[1] upperborder = 0 lowerborder = elements.shape[0] for i in range(1, nr_elements): area = stats[i, cv2.CC_STAT_AREA] if area < self.lam: result[[labels == i]] = 0 if remove_border_elements: xmin = stats[i, cv2.CC_STAT_LEFT] xmax = stats[i, cv2.CC_STAT_LEFT] + stats[i, cv2.CC_STAT_WIDTH] ymin = stats[i, cv2.CC_STAT_TOP] ymax = stats[i, cv2.CC_STAT_TOP] + stats[i, cv2.CC_STAT_HEIGHT] if xmin <= leftborder \ or xmax >= rightborder \ or ymin <= upperborder \ or ymax >= lowerborder: result[[labels == i]] = 0 if visualize: helpers.show_image(result, 'Small elements removed') return result
def getCorners(img, kernel, threshold, debug = False): img_result = cv.filter2D(img, -1, kernel) img_result[img_result > threshold] = 255 dst = cv.cornerHarris(img_result,2,3,0.04) dst = np.uint8(dst) ret, labels, stats, centroids = cv.connectedComponentsWithStats(dst) criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 100, 0.001) corners = cv.cornerSubPix(img_result,np.float32(centroids),(5,5),(-1,-1),criteria) if debug: plt.imshow(img_result, cmap = 'gray', interpolation = 'bicubic') plt.show() return corners
def extract_regions(t_img, C_range, R_range): """ Extracts region propsals for a given image """ all_boxes = [] for R in R_range: for C in C_range: s_img = cv2.morphologyEx(t_img, cv2.MORPH_CLOSE, np.ones((R, C), dtype=np.ubyte)) n, l_img, stats, centroids = cv2.connectedComponentsWithStats(s_img, connectivity=4) boxes = [[b[0], b[1], b[0] + b[2], b[1] + b[3]] for b in stats] all_boxes += boxes return all_boxes
def findRectanglesandFilter(hulls): temp[:] = 0 for cnt in hulls: area = cv2.contourArea(cnt) rect = cv2.minAreaRect(cnt) w,h = rect[1] ar = abs(w/float(h) - 1) if (w*h)/float(area) < 1.2 and ar<0.1: box = cv2.boxPoints(rect) box = np.int0(box) cv2.drawContours(temp,[box],0,255,-1) ret,labels,stats,centroids = cv2.connectedComponentsWithStats(temp) print ret return temp
def __cal_err(self, gt, pred, img=None): gt = np.array(gt) pred = np.array(pred) # TODO: sort predicted boxes by its area to prevent bigger boxes from covering the small ones. assert len(gt.shape) == len(pred.shape) == 3 # return 0 shape = img.shape if img is not None else None self.img = img if shape is None: b1 = self.__get_shape(gt) b2 = self.__get_shape(pred) shape = (max(b1[0], b2[0])+1, max(b1[1], b2[1])+1) self.img = np.zeros(shape) self.pr_map = np.zeros_like(self.img) for idx, b in enumerate(pred): cv.fillConvexPoly(self.pr_map, b, idx+1) # self.pr_map = self.pr_map*0.3 + imgs*0.7 # ===================DEBUG=================== self.gt_map = np.zeros_like(self.img) # self.gt_map = self.gt_map*0.3 + imgs*0.7 for idx, b in enumerate(gt): cv.fillConvexPoly(self.gt_map, b, idx + 1) # =========================================== errs = [] db_list = [] for idx, b in enumerate(gt): patch, gt_patch, pr_patch = self.__get_patch(b) # patch = # TODO: checking if each small box is meaningful instead of just considering its area. out = cv.connectedComponentsWithStats((patch>0).astype(np.uint8)) n_regions, label_matrix, stats, centroids = out[0], out[1], out[2], out[3] n_active_region = n_regions-1 # ignore background errs.append(n_active_region) if n_active_region > 1: db_list.append(pr_patch) errs = np.array(errs)-1 errs = (errs>0)*errs ret = {'Total error': errs.sum(), 'Mean error': errs.mean(), 'STD': errs.std()} # print(ret, db_list) return ret, db_list
def _on_update(self, *l): input_frame = self._camera.frame filtered_frame = cv2.medianBlur(input_frame, 3) hsv_frame = cv2.cvtColor(filtered_frame, cv2.COLOR_BGR2HSV) mask_by_range = cv2.inRange(hsv_frame, NimRecogniser._cap_color_low_range_hsv, NimRecogniser._cap_color_high_range_hsv) # filtered_mask = cv2.GaussianBlur(mask_by_range, (9, 9), 2, 2) # self._debug_frame = cv2.cvtColor(mask_by_range, cv2.COLOR_GRAY2BGR) kernel = np.ones((3, 3), np.uint8) opened_mask = cv2.morphologyEx(mask_by_range, cv2.MORPH_OPEN, kernel, iterations=2) dilated_mask = cv2.dilate(mask_by_range, kernel, iterations=3) distance_transform = cv2.distanceTransform(opened_mask, cv2.DIST_L2, 5) ret, threshold = cv2.threshold(opened_mask, opened_mask.max() * .7, 255, 0) ret, markers, stats, self._caps_centers = cv2.connectedComponentsWithStats(threshold) self._debug_frame = cv2.cvtColor(threshold, cv2.COLOR_GRAY2BGR) self._caps_lines = self._get_caps_lines()
def getmarkercenter(image, pos): mkradius = getapproxmarkerradius(image) buffer = int(mkradius * 0.15) roisize = mkradius + buffer # half of the height or width x = pos[0] - roisize y = pos[1] - roisize w = 2 * roisize h = 2 * roisize roi = image[y:y+h, x:x+w] grayroi = getgrayimage(roi) ret, binimage = cv2.threshold(grayroi,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(binimage) # stats[0], centroids[0] are for the background label. ignore lblareas = stats[1:,cv2.CC_STAT_AREA] ave = np.average(centroids[1:], axis=0, weights=lblareas) return tuple(np.array([x, y]) + ave) # weighted average pos of centroids
def getmarkerboundingrect(img, mkpos, mksize): buffer = int(mksize * 0.15) x = mkpos[0] - buffer y = mkpos[1] - buffer w = mksize + buffer*2 h = mksize + buffer*2 roi = img[y:y+h, x:x+w] grayroi = getgrayimage(roi) ret, binimage = cv2.threshold(grayroi,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(binimage) # stats[0], centroids[0] are for the background label. ignore # cv2.CC_STAT_LEFT, cv2.CC_STAT_TOP, cv2.CC_STAT_WIDTH, cv2.CC_STAT_HEIGHT lblareas = stats[1:,cv2.CC_STAT_AREA] imax = max(enumerate(lblareas), key=(lambda x: x[1]))[0] + 1 boundingrect = Rect(stats[imax, cv2.CC_STAT_LEFT], stats[imax, cv2.CC_STAT_TOP], stats[imax, cv2.CC_STAT_WIDTH], stats[imax, cv2.CC_STAT_HEIGHT]) return boundingrect.addoffset((x,y))
def harris_corner_detection(self, img): # find Harris corners gray = np.float32(gray) dst = cv2.cornerHarris(gray,2,3,0.04) dst = cv2.dilate(dst,None) ret, dst = cv2.threshold(dst,0.01*dst.max(),255,0) dst = np.uint8(dst) # find centroids ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst) # define the criteria to stop and refine the corners criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001) corners = cv2.cornerSubPix(gray,np.float32(centroids),(5,5),(-1,-1),criteria) # Now draw them res = np.hstack((centroids,corners)) res = np.int0(res) img[res[:,1],res[:,0]]=[0,0,255] img[res[:,3],res[:,2]] = [0,255,0]
def circleCoords(coords, mask_zero, radius = 2, maxSize = 22): mask = mask_zero[:,:,0].copy() for c in coords: cv2.circle(mask, (c[1],c[0]), radius,255,-1) ret, markers, stats, centroids = cv2.connectedComponentsWithStats(mask) if visualize:#for visualization only max_ = np.amax(markers) markers *= 255/max_ markers = markers.astype(np.uint8) markers_col = cv2.applyColorMap(markers, cv2.COLORMAP_JET) candidates = [] for (i,c) in enumerate(centroids): if (stats[i,cv2.CC_STAT_WIDTH] < maxSize and stats[i,cv2.CC_STAT_HEIGHT] < maxSize and (stats[i,cv2.CC_STAT_WIDTH] > 4*radius or stats[i,cv2.CC_STAT_HEIGHT] >4*radius)): if visualize: cv2.circle(markers_col, (int(c[0]),int(c[1])), maxSize/2,(0,0,255),1) candidates += [c] if visualize:#for visualization only cv2.imshow('markers_col', markers_col) return candidates
def select_largest_obj(self, img_bin, lab_val=255, fill_holes=False, smooth_boundary=False, kernel_size=15): '''Select the largest object from a binary image and optionally fill holes inside it and smooth its boundary. Args: img_bin (2D array): 2D numpy array of binary image. lab_val ([int]): integer value used for the label of the largest object. Default is 255. fill_holes ([boolean]): whether fill the holes inside the largest object or not. Default is false. smooth_boundary ([boolean]): whether smooth the boundary of the largest object using morphological opening or not. Default is false. kernel_size ([int]): the size of the kernel used for morphological operation. Default is 15. Returns: a binary image as a mask for the largest object. ''' n_labels, img_labeled, lab_stats, _ = \ cv2.connectedComponentsWithStats(img_bin, connectivity=8, ltype=cv2.CV_32S) largest_obj_lab = np.argmax(lab_stats[1:, 4]) + 1 largest_mask = np.zeros(img_bin.shape, dtype=np.uint8) largest_mask[img_labeled == largest_obj_lab] = lab_val # import pdb; pdb.set_trace() if fill_holes: bkg_locs = np.where(img_labeled == 0) bkg_seed = (bkg_locs[0][0], bkg_locs[1][0]) img_floodfill = largest_mask.copy() h_, w_ = largest_mask.shape mask_ = np.zeros((h_ + 2, w_ + 2), dtype=np.uint8) cv2.floodFill(img_floodfill, mask_, seedPoint=bkg_seed, newVal=lab_val) holes_mask = cv2.bitwise_not(img_floodfill) # mask of the holes. largest_mask = largest_mask + holes_mask if smooth_boundary: kernel_ = np.ones((kernel_size, kernel_size), dtype=np.uint8) largest_mask = cv2.morphologyEx(largest_mask, cv2.MORPH_OPEN, kernel_) return largest_mask
def removeStemPre(img): se = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(9,9)) #img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, se) img = cv2.morphologyEx(img, cv2.MORPH_OPEN, se) # Connected Component Analysis ret, labels, stats, centroids = cv2.connectedComponentsWithStats(img) maxLabel = 0 maxSize = 0 for i in range( ret ): sizeOfComp = np.sum(labels==i) if sizeOfComp > maxSize and not (stats[i,0]==0 and stats[i,1]==0): maxSize = sizeOfComp maxLabel = i for i in range( ret ): if i != maxLabel: img[ labels==i ] = 0 return img
img02 = cv2.cvtColor(img01,cv2.COLOR_BGR2GRAY) #%% カラー次元 img03 = cv2.cvtColor(img02,cv2.COLOR_GRAY2BGR) #%% 輪郭抽出 #引数1:画像、引数2:輪郭検索モード、引数3:輪郭近似方法 img04,contours,hierarchy = cv2.findContours(img02, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) rects=[] for contour in contours: approx = cv2.convexHull(contour) rect = cv2.boundingRect(approx) rects.append(np.array(rect)) #%% ラベリング2 img06 = img01.copy() #戻り。0:個数、1:labelImageと同じ、2:?、3:重心座標 label = cv2.connectedComponentsWithStats(bin) # ラベルの個数 n=label[0]-1 # 重心位置 cog = np.delete(label[3],0,0) # 重心に赤円を描く for i in range(n): img06 = cv2.circle(img06,(int(cog[i][0]),int(cog[i][1])), 2, (0,0,255), -1) #%% plt.imshow(img06)
def get_regions_of_interest(self, filtered, prev_filtered=None): """ Calculates pixels of interest mask from filtered image, and returns both the labeled mask and their bounding rectangles. :param filtered: The filtered frame :param prev_filtered: The previous filtered frame, required for pixel deltas to be calculated :return: regions of interest, mask frame """ frame_height, frame_width = filtered.shape # get frames change if prev_filtered is not None: # we need a lot of precision because the values are squared. Float32 should work. delta_frame = np.abs( np.float32(filtered) - np.float32(prev_filtered)) else: delta_frame = None # remove the edges of the frame as we know these pixels can be spurious value edgeless_filtered = self.crop_rectangle.subimage(filtered) thresh = np.uint8( blur_and_return_as_mask(edgeless_filtered, threshold=self.threshold)) dilated = thresh # Dilation groups interested pixels that are near to each other into one component(animal/track) if self.config.dilation_pixels > 0: size = self.config.dilation_pixels * 2 + 1 kernel = np.ones((size, size), np.uint8) dilated = cv2.dilate(dilated, kernel, iterations=1) labels, small_mask, stats, _ = cv2.connectedComponentsWithStats( dilated) # make mask go back to full frame size without edges chopped edge = self.config.edge_pixels mask = np.zeros(filtered.shape, dtype=np.int32) mask[edge:frame_height - edge, edge:frame_width - edge] = small_mask # we enlarge the rects a bit, partly because we eroded them previously, and partly because we want some context. padding = self.frame_padding # find regions of interest regions = [] for i in range(1, labels): region = Region( stats[i, 0], stats[i, 1], stats[i, 2], stats[i, 3], stats[i, 4], 0, i, self.frame_on, ) # want the real mass calculated from before the dilation region.mass = np.sum(region.subimage(thresh)) # Add padding to region and change coordinates from edgeless image -> full image region.x += edge - padding region.y += edge - padding region.width += padding * 2 region.height += padding * 2 old_region = region.copy() region.crop(self.crop_rectangle) region.was_cropped = str(old_region) != str(region) if self.config.cropped_regions_strategy == "cautious": crop_width_fraction = (old_region.width - region.width) / old_region.width crop_height_fraction = (old_region.height - region.height) / old_region.height if crop_width_fraction > 0.25 or crop_height_fraction > 0.25: continue elif self.config.cropped_regions_strategy == "none": if region.was_cropped: continue elif self.config.cropped_regions_strategy != "all": raise ValueError( "Invalid mode for CROPPED_REGIONS_STRATEGY, expected ['all','cautious','none'] but found {}" .format(self.config.cropped_regions_strategy)) if delta_frame is not None: region_difference = np.float32(region.subimage(delta_frame)) region.pixel_variance = np.var(region_difference) # filter out regions that are probably just noise if (region.pixel_variance < self.config.aoi_pixel_variance and region.mass < self.config.aoi_min_mass): continue regions.append(region) return regions, mask
def to_centroids(img_, gray): ret, labels, stats, centroids = cv2.connectedComponentsWithStats(img_) criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001) corners = cv2.cornerSubPix(gray, np.float32(centroids), (5, 5), (-1, -1), criteria) return centroids, corners
def counting_components(connectivity, inputfile): src = cv2.imread(inputfile, 0) binary_map = (src < 255).astype(np.uint8) output = cv2.connectedComponentsWithStats(binary_map, connectivity, cv2.CV_32S) return output[0]
def blob_detector (img, x_i, y_i): img = cv2.Canny(img, 100, 200) blobs = [] #get connected components of fg output = cv2.connectedComponentsWithStats(img, 4, cv2.CV_32S) # Get the results # The first cell is the number of labels num_labels = output[0] # The second cell is the label matrix labels = output[1] # The third cell is the stat matrix stats = output[2] # The fourth cell is the centroid matrix centroids = output[3] #print (centroids) #print(np.where(labels == 2)) component_centroids = {} for i in range (1, num_labels): #get component centroid coordinates x,y = centroids[i] #compute statistics width = stats[i,cv2.CC_STAT_WIDTH] height = stats[i, cv2.CC_STAT_HEIGHT] radius = (height + width)/2 area = stats[i, cv2.CC_STAT_AREA] #these are the top left x, y coordinates = ONLY TO BE USED FOR GETTING ROI x_l = stats[i,cv2.CC_STAT_LEFT] y_l = stats[i,cv2.CC_STAT_TOP] #remove everything except for component i to create isolated component matrix component_matrix = [[1 if m== i else 0 for m in marker] for marker in labels] #get connected component roi roi = img[y_l: y_l+height, x_l:x_l+width] #----------------MEASURES------------------------------------------------------------------- #radius = (height + width)/2 radius = np.sqrt((area/np.pi)) formfactor = compute_formfactor (radius, area) if height > width: roundness = compute_roundness (height, radius, area) aspect_ratio = height/width else: roundness = compute_roundness (width, radius, area) aspect_ratio = width/height #print ("radius: " + str(radius) + ", formfactor: " + str(formfactor) + ", roundness: " + str(roundness) + ", aspect ratio: " + str(aspect_ratio)) print ("area: " + str(area)) print("Roundness: " + str(roundness)) print("aspect_ratio: " + str(aspect_ratio)) print("formfactor: " + str(formfactor)) print ("(" + str(x) + ","+str(y)+")") print ("\n") #WRONG X,Y COORDINATE! if roundness > 0.2 and 0.9 < aspect_ratio < 1.5 and 1.1 >= formfactor > 0.9: print ("is circle") blob = Blob() blob.radius = radius blob.x = x+x_i blob.y = y+y_i blob.matrix = component_matrix blob.roi = roi blobs.append(blob) #cv2.imshow("roi", roi) #cv2.waitKey(0) return blobs
# 读出预先准备的图片 img = cv2.imread( r'D:\pythonProject\pythonLearning\gameCheat\findDifference\picSource\pic3.PNG', cv2.IMREAD_COLOR) # 转换图片的格式,从BGR转换为HSV img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) # 进行一些简单的滤波 img_gray_blur = cv2.GaussianBlur(img_gray, (5, 5), 0) # 找两张图片的位置 # 二值化 img_gray_blur_threshold = cv2.adaptiveThreshold(img_gray_blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) # 区域连通,区分object _, labels, stats, _ = cv2.connectedComponentsWithStats(img_gray_blur_threshold) # 找出两个图形的区域,这里的筛选条件为,面积为60000-63000 # 注,这里的筛选条件对于不同的屏幕分辨率会有偏差。如果能如果使用后面三个参数同时匹配会更好,即,长宽面积相近时 regions = [x for x in stats if 400 > x[2] > 380] region_width = min(regions[0][2], regions[1][2]) region_height = min(regions[0][3], regions[1][3]) regions1 = regions[0] img_detect1 = img_gray_blur[regions1[1]:regions1[1] + region_height, regions1[0]:regions1[0] + region_width] regions1 = regions[1] img_detect2 = img_gray_blur[regions1[1]:regions1[1] + region_height, regions1[0]:regions1[0] + region_width] img_detect1_int16 = np.int16(img_detect1)
def draw_binary_mask(self, binary_mask, color=None, *, edge_color=None, text=None, alpha=0.5, area_threshold=4096): """ Args: binary_mask (ndarray): numpy array of shape (H, W), where H is the image height and W is the image width. Each value in the array is either a 0 or 1 value of uint8 type. color: color of the mask. Refer to `matplotlib.colors` for a full list of formats that are accepted. If None, will pick a random color. edge_color: color of the polygon edges. Refer to `matplotlib.colors` for a full list of formats that are accepted. text (str): if None, will be drawn in the object's center of mass. alpha (float): blending efficient. Smaller values lead to more transparent masks. area_threshold (float): a connected component small than this will not be shown. Returns: output (VisImage): image object with mask drawn. """ if color is None: color = random_color(rgb=True, maximum=1) if area_threshold is None: area_threshold = 4096 has_valid_segment = False binary_mask = binary_mask.astype("uint8") # opencv needs uint8 mask = GenericMask(binary_mask, self.output.height, self.output.width) shape2d = (binary_mask.shape[0], binary_mask.shape[1]) if not mask.has_holes: # draw polygons for regular masks for segment in mask.polygons: area = mask_util.area( mask_util.frPyObjects([segment], shape2d[0], shape2d[1])) if area < area_threshold: continue has_valid_segment = True segment = segment.reshape(-1, 2) self.draw_polygon(segment, color=color, edge_color=edge_color, alpha=alpha) else: rgba = np.zeros(shape2d + (4, ), dtype="float32") rgba[:, :, :3] = color rgba[:, :, 3] = (mask.mask == 1).astype("float32") * alpha has_valid_segment = True self.output.ax.imshow(rgba) if text is not None and has_valid_segment: # TODO sometimes drawn on wrong objects. the heuristics here can improve. lighter_color = self._change_color_brightness( color, brightness_factor=0.7) _num_cc, cc_labels, stats, centroids = cv2.connectedComponentsWithStats( binary_mask, 8) largest_component_id = np.argmax(stats[1:, -1]) + 1 # draw text on the largest component, as well as other very large components. for cid in range(1, _num_cc): if cid == largest_component_id or stats[ cid, -1] > _LARGE_MASK_AREA_THRESH: # median is more stable than centroid # center = centroids[largest_component_id] center = np.median((cc_labels == cid).nonzero(), axis=1)[::-1] self.draw_text(text, center, color=lighter_color) return self.output
if "DS" in images: os.remove(images) img_clr = cv2.imread(images) img_clr = cv2.resize(img_clr, (1000, 1000)) img_gray = cv2.cvtColor(img_clr, cv2.COLOR_BGR2GRAY) hi, wi, c = img_clr.shape img_sob = sobel(img_gray) img_thres = cv2.threshold(img_sob, 127, 255, cv2.THRESH_BINARY)[1] kernel = np.ones((5, 5)) img_dilate = cv2.dilate(img_thres, kernel, iterations=3) img_erode = cv2.erode(img_dilate, kernel, iterations=3) boxs = [] result = [] nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats( img_erode) lblareas = stats[:, cv2.CC_STAT_AREA] for j in range(1, len(lblareas)): if lblareas[j] > 1000: scaler = 0 x = stats[j, cv2.CC_STAT_LEFT] - scaler y = stats[j, cv2.CC_STAT_TOP] - scaler w = stats[j, cv2.CC_STAT_WIDTH] + scaler * 2 h = stats[j, cv2.CC_STAT_HEIGHT] + scaler * 2 temp = np.copy(img_clr[y:y + h, x:x + w]) b, g, r = cv2.split(temp) gray = cv2.cvtColor(temp, cv2.COLOR_BGR2GRAY) temp_sob = sobel(gray)
def callback(data): Datamatrix = data.data bridge = CvBridge() # rospy.loginfo("I heard %0.6f", data.data) try: # cv_image = bridge.imgmsg_to_cv2(data, "mono8") cv_image = bridge.imgmsg_to_cv2( data, desired_encoding='passthrough') # output cv:mat gray = cv_image ##### initilization ##################excute only once in the beginning#################33 ##### -binarization ##### -Hough circle, ##### - find max diameter # binarization # Global threshoding # ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE) # # print("threshold value: %s"%ret) # partitial thresholding # binary1 = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY, 25, 10) ##### max gradient threshold method h, w = cv_image.shape[:2] m = np.reshape(gray, [1, w * h]) #<size> (1, 316224) #turple 元祖类型 m_sort = sorted(m[0, :], reverse=True) step = 30 v2 = m_sort[:-step] v1 = m_sort[step:] m_sort_diff = [] for i in range(0, (len(m_sort) - step - 1)): diff = v2[i] - v1[i] m_sort_diff.append(diff) max_index = m_sort_diff.index(max(m_sort_diff)) # print("max index = %d" %max_index) thresh = m_sort[max_index + step] # print("tresh = %d" %thresh) ret, binary = cv.threshold(gray, thresh, 255, cv.THRESH_BINARY) # canny = cv.Canny(binary, 50, 150) # 50是最小阈值,150是最大阈值 ####### hough circle # circle = cv2.HoughCircles(binary, cv2.HOUGH_GRADIENT, 1, 200, param1=50, param2=30, minRadius=50, maxRadius=300) circle = cv.HoughCircles(binary, cv.HOUGH_GRADIENT, 1.4, 1, param1=300, param2=21, minRadius=5, maxRadius=20) #dpi, minDist # circle = cv.HoughCircles(cv_image, cv.HOUGH_GRADIENT,1, 1,param1=255, param2=25,minRadius=5,maxRadius=20) #dpi, minDist if not circle is None: circle = np.uint16(np.around(circle)) print(circle) else: print("no circle is detected!") #### detect connected areas and their centers # 搜索图像中的连通区域 ret, labels, stats, centroid = cv.connectedComponentsWithStats(binary) # # Set up the detector with default parameters. # detector = cv.SimpleBlobDetector() # # Detect blobs. # keypoints = detector.detect(binary) except CvBridgeError as e: print(e) cv_imageBGR = cv.cvtColor(cv_image, cv.COLOR_GRAY2BGR) cv.namedWindow("image_raw", cv.WINDOW_NORMAL) cv.imshow("image_raw", cv_image) cv.imwrite('image_raw_fibers.png', cv_image) # cv.namedWindow("binary", cv.WINDOW_NORMAL) # cv.imshow("binary", binary) # cv.circle(cv_image, (50,50), 10, 255) #draw a circle for each light spot ### draw hough circles # if not circle is None: # count = 0 # for i in circle[0, :]: # cv.circle(cv_imageBGR, (i[0], i[1]), i[2], (0, 0, 255)) # count = count+1 # print("number of circle = %d" %count ) # cv.imshow("Image window", cv_imageBGR) # cv.waitKey(3) ### remove small connected areas: diameter<5 # num = 0 # circle_connected = empty([24,3]) # for i, stat in enumerate(stats): # if stat[4]>100: # circle_connected[num,0] = stat[0] + stat[2]/2 # circle_connected[num,1] = stat[1] + stat[3]/2 # circle_connected[num,2] = stat[2] if stat[2]>stat[3] else stat[3] # num = num+1 # print("num = %d" %num) # ## draw connected areas # for i, stat in enumerate(circle_connected): # #绘制连通区域 # # cv.rectangle(cv_imageBGR, (stat[0], stat[1]), (stat[0] + stat[2], stat[1] + stat[3]), (25, 25, 255), 3) # cv.circle(cv_imageBGR,(stat[0], stat[1]), stat[2], (0,0,255)) # #按照连通区域的索引来打上标签 # cv.putText(cv_imageBGR, str(i+1), (stat[0], stat[1] + 25), cv.FONT_HERSHEY_SIMPLEX, 0.8, (255, 25, 25), 2) # cv.imshow("Image window", cv_imageBGR) # # Draw detected blobs as red circles. # # cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of the circle corresponds to the size of blob # im_with_keypoints = cv.drawKeypoints(cv_imageBGR, keypoints, np.array([]), (0,0,255), cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) # # Show keypoints # cv.namedWindow("Keypoints", cv.WINDOW_NORMAL) # cv.imshow("Keypoints", im_with_keypoints) # plt.subplot(111) # plt.imshow(cv_image) # plt.xticks([]) # plt.yticks([]) cv.waitKey(3)
def image_process(): cv_image = cv.imread("image_raw_fibers.png") # test # cv_image = drawcicle(cv_image) # gray = cv_image gray = cv.cvtColor(cv_image, cv.COLOR_BGR2GRAY) cv_imageBGR = cv_image # cv.cvtColor(cv_image, cv.COLOR_GRAY2BGR ) ##### max gradient threshold method h, w = gray.shape[:2] print(gray.shape) print("h=%d" % h) print("w=%d" % w) print("w*h=%d" % (w * h)) m = np.reshape(gray, [1, w * h]) #<size> (1, 316224) #turple 元祖类型 m_sort = sorted(m[0, :], reverse=True) step = 30 v2 = m_sort[:-step] v1 = m_sort[step:] m_sort_diff = [] for i in range(0, (len(m_sort) - step - 1)): diff = v2[i] - v1[i] m_sort_diff.append(diff) max_index = m_sort_diff.index(max(m_sort_diff)) # print("max index = %d" %max_index) thresh = m_sort[max_index + step] # print("tresh = %d" %thresh) ret, binary = cv.threshold(gray, thresh, 255, cv.THRESH_BINARY) #### detect connected areas and their centers # 搜索图像中的连通区域 ret, labels, stats, centroid = cv.connectedComponentsWithStats(binary) #ret: number of labels #labels: label each connected area from 1 to n #stats: a matrix with each line includes (center_x, center_y, width_x, hight_y, area) # here center_x means column, and center_y means rows, reverse to index of array!!!!!!!!!!!!!!!!!! ### remove small connected areas: diameter<5 num = 0 circlenum = 24 #----------------------------defind circle number here circle_dected = empty([circlenum, 3]) for i, stat in enumerate(stats): if stat[4] > 100 and stat[4] < 1000: circle_dected[num, 0] = int(stat[0] + stat[2] / 2) # center_x circle_dected[num, 1] = int(stat[1] + stat[3] / 2) # center_y circle_dected[num, 2] = int( stat[2] / 2) + 1 if stat[2] > stat[3] else int(stat[3] / 2) + 1 # radius num = num + 1 print("detected circle num = %d" % num) print(circle_dected) pixelvalue = [] pixelnum = [] circle_pixel = empty([circlenum, 2]) #### calculate total pixel value in each circle for i, stat in enumerate(circle_dected): pixelvalreturn, pixelnumreturn = calculatepixelvalue( stat[0], stat[1], stat[2], gray) pixelvalue.append(pixelvalreturn) pixelnum.append(pixelnumreturn) circle_pixel[i, 0] = pixelvalreturn circle_pixel[i, 1] = pixelnumreturn print("%dth circle pixelvalue is: %d, pixelnum is %d" % (i + 1, pixelvalreturn, pixelnumreturn)) circle_stats = np.hstack( (circle_dected, circle_pixel )) # center_x(column), center_y(row),radius,pixelvalue,pixelnum print(circle_stats) # np.savetxt('circle_stats.csv',circle_stats,delimiter=',') filename = 'cilcle_detected.csv' header = [ "center_x(column)", "center_y(row)", "radius", "pixelvalue", "pixelnum" ] savedata_csv(filename, header, circle_stats) cv.namedWindow("image_raw", cv.WINDOW_NORMAL) cv.imshow("image_raw", cv_image) ## draw connected areas for i, stat in enumerate(circle_dected): #绘制连通区域 # cv.rectangle(cv_imageBGR, (stat[0], stat[1]), (stat[0] + stat[2], stat[1] + stat[3]), (25, 25, 255), 3) cv.circle(cv_imageBGR, (int(stat[0]), int(stat[1])), int(stat[2]), (0, 0, 255)) #按照连通区域的索引来打上标签 cv.putText(cv_imageBGR, str(i + 1), (int(stat[0]), int(stat[1]) + 25), cv.FONT_HERSHEY_SIMPLEX, 0.5, (255, 25, 25), 1) # cv.circle(cv_imageBGR,(10,50),2,(0,0,255)) cv.namedWindow("Image window", cv.WINDOW_NORMAL) cv.imshow("Image window", cv_imageBGR) cv.imwrite("circled image.png", cv_imageBGR) # cv.waitKey() k = cv.waitKey(0) ## k = cv2.waitKey(0) & 0xFF # 64位机器 if k == 27: # 按下esc时,退出 cv.destroyAllWindows()
def getConnectedComponents(characterImage): connectivity = 8 output = cv2.connectedComponentsWithStats(characterImage, connectivity, cv2.CV_32S) return output[0] #this is the number of labels
def updatePosition(self, robot_obj, imageManager): image_name = None ## Step 0 : Get the most recent image from directory Images frame_rgb = None # Reason for while loop is to ensure that we've successfully fetched image file. # Without the while loop, there was a chance for a case where fetching image failed # Instead of using cv2.imread, we use skimage.imread to detect corrupted jpeg files. while True: image_name = imageManager.getRecentImageName() try: frame_rgb = io.imread('./S_CameraVision/Images/' + image_name) except: print("Pre-mature end of JPEG File, Re-try") continue break print(image_name) ## Step 1 : Detect Points with Particular Color # Converting RGB to HSV - Robot robot_color_rgb = robot_obj.getColorRGB() robot_color_rgb_pixel = np.uint8([[robot_color_rgb]]) robot_color_hsv = cv2.cvtColor(robot_color_rgb_pixel, cv2.COLOR_RGB2HSV) robot_color_hsv = robot_color_hsv[0][0] # Converting BGR to HSV - Image frame_bgr = cv2.cvtColor(frame_rgb, cv2.COLOR_RGB2BGR) frame_hsv = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2HSV) # Masking - Color mask = None if (robot_color_hsv[2] <= 50): # Black (Useless) mask_l = np.array([0, 0, 0]) mask_u = np.array([180, 255, 50]) mask = cv2.inRange(frame_hsv, mask_l, mask_u) elif (robot_color_hsv[2] >= 205): # White (Useless) mask_l = np.array([0, 0, 205]) mask_u = np.array([180, 255, 255]) mask = cv2.inRange(frame_hsv, mask_l, mask_u) elif (robot_color_hsv[0] < config["COLOR_SENSITIVITY"]): mask0_l = np.array([0, 30, 30]) mask0_u = np.array( [robot_color_hsv[0] + config["COLOR_SENSITIVITY"], 255, 255]) mask0 = cv2.inRange(frame_hsv, mask0_l, mask0_u) mask1_l = np.array([ robot_color_hsv[0] + 180 - config["COLOR_SENSITIVITY"], 30, 30 ]) mask1_u = np.array([180, 255, 255]) mask1 = cv2.inRange(frame_hsv, mask1_l, mask1_u) mask = mask0 + mask1 elif (180 - robot_color_hsv[0] < config["COLOR_SENSITIVITY"]): mask0_l = np.array( [robot_color_hsv[0] - config["COLOR_SENSITIVITY"], 30, 30]) mask0_u = np.array([180, 255, 255]) mask0 = cv2.inRange(frame_hsv, mask0_l, mask0_u) mask1_l = np.array([0, 30, 30]) mask1_u = np.array([ robot_color_hsv[0] + config["COLOR_SENSITIVITY"] - 180, 255, 255 ]) mask1 = cv2.inRange(frame_hsv, mask1_l, mask1_u) mask = mask0 + mask1 else: mask_l = np.array( [robot_color_hsv[0] - config["COLOR_SENSITIVITY"], 30, 30]) mask_u = np.array( [robot_color_hsv[0] + config["COLOR_SENSITIVITY"], 255, 255]) mask = cv2.inRange(frame_hsv, mask_l, mask_u) # Masking - Morphology (Clustering) kernel = np.ones((11, 11), np.uint8) mask_morph_open = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) mask_morph = cv2.morphologyEx(mask_morph_open, cv2.MORPH_CLOSE, kernel) # Filtered Image Frame frame_filtered = cv2.bitwise_and(frame_bgr, frame_bgr, mask=mask_morph) cv2.imwrite("./S_CameraVision/Images_Box/Filtered/" + image_name, frame_filtered) # Labeling - Clustering numOfLabels, img_label, stats, centroids = cv2.connectedComponentsWithStats( mask_morph) # Fetch Indices of Stickers sticker_indices = [] for idx, centroid in enumerate(centroids): if (stats[idx][0] == 0 and stats[idx][1] == 0): continue if (np.any(np.isnan(centroid))): continue x, y, width, height, area = stats[idx] centerX, centerY = int(centroid[0]), int(centroid[1]) # Adding Index in List sticker_indices.append((centerX, centerY)) cv2.rectangle(frame_bgr, (x, y), (x + width, y + height), (0, 0, 255)) # TODO: Delete (Testing Purpose Only) sticker_indices = [[250, 250], [400, 400], [400, 150]] cv2.imwrite('./S_CameraVision/Images_Box/Sticker/' + image_name, frame_bgr) # Calculation of Direction Vector & Position # assert (len(sticker_indices) == 3) # 3 Stickers! ### TODO : FAILURE ? # TODO: While Loop until passes assert condition ## Step 2 : Indicate the Center Point of Robot Arms with infos from Step 1 d0_1 = np.sum((np.array(sticker_indices[0:1]))**2) d1_2 = np.sum((np.array(sticker_indices[1:2]))**2) d0_2 = np.sum((np.array([sticker_indices[0], sticker_indices[2]]))**2) dist = [d0_1, d0_2, d1_2] # print ("sticker_indices : " + str(sticker_indices)) # print ("dist : " + str(dist)) point_head = None point_shoulder = None if (min(dist) == d0_1): point_head = sticker_indices[2] point_shoulder = [sticker_indices[0], sticker_indices[1]] elif (min(dist) == d1_2): point_head = sticker_indices[0] point_shoulder = [sticker_indices[1], sticker_indices[2]] else: point_head = sticker_indices[1] point_shoulder = [sticker_indices[0], sticker_indices[2]] # print ("point_head : " + str(point_head)) # print ("point_shoulder : " + str(point_shoulder)) # Calculation of Direction Vector & Center # Direction Vector mid_point = np.array(point_shoulder[0]) + np.array(point_shoulder[1]) mid_point = mid_point / 2 dir_vector = np.array(point_head) - mid_point dir_vector_size = np.sum(dir_vector**2)**0.5 dir_vector_unit = dir_vector / dir_vector_size # print ("mid_point : " + str(mid_point)) # print ("dir_vector : " + str(dir_vector)) # print ("dir_vector_size : " + str(dir_vector_size)) # print ("dir_vector_unit : " + str(dir_vector_unit)) # Center Position Data robot_cent_XY_pixel_np = np.array( point_head) + dir_vector_unit * config[ "CENTER_DIST_FROM_STICKER_MM"] / config["MM_PER_PIXEL"] robot_cent_XY_pixel = np.ndarray.tolist(robot_cent_XY_pixel_np) # print ("Center : " + str(robot_cent_XY_pixel)) # Convert pixel into mm robot_cent_XY_mm = ConvertPixel2Real.Pixel2Real(robot_cent_XY_pixel) # robot_cent_XY_mm = [50, 50] print("Center (mm) : " + str(robot_cent_XY_mm)) # Saving Information in Robot Object robot_cent_XY_mm_obj = [] robot_cent_XY_mm_obj.extend(robot_cent_XY_mm) robot_cent_XY_mm_obj.append(0) robot_obj.setPos_position(robot_cent_XY_mm_obj) dir_vector_unit_obj = [] dir_vector_unit_obj.extend(dir_vector_unit) dir_vector_unit_obj.append(0) robot_obj.setPos_angle(dir_vector_unit_obj) ## Step 3 : Drawing Circle center = (int(robot_cent_XY_pixel[0]), int(robot_cent_XY_pixel[1])) radian = int(config["ROBOT_BODY_SIZE_MM"] / config["MM_PER_PIXEL"]) color = (255, 0, 0) thickness = 2 cv2.circle(frame_bgr, center, radian, color, thickness) cv2.imwrite('./S_CameraVision/Images_Box/Robot/' + image_name, frame_bgr) self.updated_image_conn.emit( robot_obj, './S_CameraVision/Images_Box/Robot/' + image_name)
def largest_component(mask): retval, labels, stats, centroids = cv2.connectedComponentsWithStats(mask) index = np.argmax(stats[1:,4]) mask = np.uint8(labels == index + 1) return mask
def color_cluster_seg(image, args_colorspace, args_channels, args_num_clusters): # Change image color space, if necessary. colorSpace = args_colorspace.lower() if colorSpace == 'hsv': image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) elif colorSpace == 'ycrcb' or colorSpace == 'ycc': image = cv2.cvtColor(image, cv2.COLOR_BGR2YCrCb) elif colorSpace == 'lab': image = cv2.cvtColor(image, cv2.COLOR_BGR2LAB) else: colorSpace = 'bgr' # set for file naming purposes # Keep only the selected channels for K-means clustering. if args_channels != 'all': channels = cv2.split(image) channelIndices = [] for char in args_channels: channelIndices.append(int(char)) image = image[:, :, channelIndices] if len(image.shape) == 2: image.reshape(image.shape[0], image.shape[1], 1) (width, height, n_channel) = image.shape #print("image shape: \n") #print(width, height, n_channel) # Flatten the 2D image array into an MxN feature vector, where M is the number of pixels and N is the dimension (number of channels). reshaped = image.reshape(image.shape[0] * image.shape[1], image.shape[2]) # Perform K-means clustering. if args_num_clusters < 2: print('Warning: num-clusters < 2 invalid. Using num-clusters = 2') #define number of cluster numClusters = max(2, args_num_clusters) # clustering method kmeans = KMeans(n_clusters=numClusters, n_init=40, max_iter=500).fit(reshaped) # get lables pred_label = kmeans.labels_ # Reshape result back into a 2D array, where each element represents the corresponding pixel's cluster index (0 to K - 1). clustering = np.reshape(np.array(pred_label, dtype=np.uint8), (image.shape[0], image.shape[1])) # Sort the cluster labels in order of the frequency with which they occur. sortedLabels = sorted([n for n in range(numClusters)], key=lambda x: -np.sum(clustering == x)) # Initialize K-means grayscale image; set pixel colors based on clustering. kmeansImage = np.zeros(image.shape[:2], dtype=np.uint8) for i, label in enumerate(sortedLabels): kmeansImage[clustering == label] = int(255 / (numClusters - 1)) * i ret, thresh = cv2.threshold(kmeansImage, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) thresh_cleaned = clear_border(thresh) if np.count_nonzero(thresh) > 0: thresh_cleaned_bw = clear_border(thresh) else: thresh_cleaned_bw = thresh nb_components, output, stats, centroids = cv2.connectedComponentsWithStats( thresh_cleaned, connectivity=8) # stats[0], centroids[0] are for the background label. ignore # cv2.CC_STAT_LEFT, cv2.CC_STAT_TOP, cv2.CC_STAT_WIDTH, cv2.CC_STAT_HEIGHT sizes = stats[1:, cv2.CC_STAT_AREA] Coord_left = stats[1:, cv2.CC_STAT_LEFT] Coord_top = stats[1:, cv2.CC_STAT_TOP] Coord_width = stats[1:, cv2.CC_STAT_WIDTH] Coord_height = stats[1:, cv2.CC_STAT_HEIGHT] Coord_centroids = centroids #print("Coord_centroids {}\n".format(centroids[1][1])) #print("[width, height] {} {}\n".format(width, height)) nb_components = nb_components - 1 min_size = 50 max_size = width * height * 0.1 img_thresh = np.zeros([width, height], dtype=np.uint8) #for every component in the image, keep it only if it's above min_size for i in range(0, nb_components): #print("{} nb_components found".format(i)) ''' if (sizes[i] >= min_size) and (Coord_left[i] > 1) and (Coord_top[i] > 1) and (Coord_width[i] - Coord_left[i] > 0) and (Coord_height[i] - Coord_top[i] > 0) and (centroids[i][0] - width*0.5 < 10) and ((centroids[i][1] - height*0.5 < 10)) and ((sizes[i] <= max_size)): img_thresh[output == i + 1] = 255 print("Foreground center found ") elif ((Coord_width[i] - Coord_left[i])*0.5 - width < 15) and (centroids[i][0] - width*0.5 < 15) and (centroids[i][1] - height*0.5 < 15) and ((sizes[i] <= max_size)): imax = max(enumerate(sizes), key=(lambda x: x[1]))[0] + 1 img_thresh[output == imax] = 255 print("Foreground max found ") ''' if (sizes[i] >= min_size): img_thresh[output == i + 1] = 255 #from skimage import img_as_ubyte #img_thresh = img_as_ubyte(img_thresh) #print("img_thresh.dtype") #print(img_thresh.dtype) #return img_thresh return img_thresh
def main(): cap = cv2.VideoCapture(vid_path) ret, previous_frame1 = cap.read() previous_frame = cv2.cvtColor(previous_frame1, cv2.COLOR_BGR2GRAY) fgbg = cv2.createBackgroundSubtractorMOG2() hsv = np.zeros_like(previous_frame1) hsv[..., 1] = 255 t = 20 dc = 6 red = 30 check_red = 1 start = 0 radiuce_up_limit = 60 radiuce_low_limit = 30 i = 0 breathing = 0 n_breathing = 0 total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) while (i < total_frames - 1): ret, frame = cap.read() current_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) current_frame = cv2.GaussianBlur(current_frame, (13, 13), 0) fgmask = fgbg.apply(current_frame) copy = fgmask.copy() lab_val = 255 n_labels, img_labeled, lab_stats, _ = \ cv2.connectedComponentsWithStats(copy, connectivity=8, ltype=cv2.CV_32S) if check_red == 1: red = red + 10 if red > radiuce_up_limit: check_red = 0 else: red = red - 10 if red == radiuce_low_limit: check_red = 1 if lab_stats[1:, 4].size > 2: start = 1 dc = dc + 1 if dc > 6: dc = 0 re = lab_stats[1:, 4].argsort()[-3:][::-1] + 1 largest_mask = np.zeros(copy.shape, dtype=np.uint8) largest_mask[img_labeled == re[0]] = lab_val cnts1 = cv2.findContours(largest_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts1 = cnts1[0] if imutils.is_cv2() else cnts1[1] largest_mask[img_labeled == re[1]] = lab_val cnts2 = cv2.findContours(largest_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts2 = cnts2[0] if imutils.is_cv2() else cnts2[1] largest_mask[img_labeled == re[2]] = lab_val cnts3 = cv2.findContours(largest_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts3 = cnts3[0] if imutils.is_cv2() else cnts3[1] X1 = cnts3[0][0] X2 = cnts3[1][0] X3 = cnts3[2][0] cX1 = X1[0][0] cY1 = X1[0][1] cX2 = X2[0][0] cY2 = X2[0][1] cX3 = X3[0][0] cY3 = X3[0][1] # distance between obj1 and obj2 dist1 = math.sqrt((cX1 - cX2)**2 + (cY1 - cY2)**2) dist2 = math.sqrt((cX1 - cX3)**2 + (cY1 - cY3)**2) dist3 = math.sqrt((cX2 - cX3)**2 + (cY2 - cY3)**2) if dist1 < 90: cX2 = cX1 cY2 = cY1 radiuce_up_limit = 100 else: radiuce_up_limit = 60 if dist2 < 90: cX3 = cX2 cY3 = cY2 radiuce_up_limit = 100 else: radiuce_up_limit = 60 if dist3 < 90: cX2 = cX3 cY2 = cY3 radiuce_up_limit = 100 else: radiuce_up_limit = 60 cv2.circle(frame, (cX1, cY1), red, (0, 255, 255), 3) cv2.circle(frame, (cX2, cY2), red, (0, 255, 255), 3) cv2.circle(frame, (cX3, cY3), red, (0, 255, 255), 3) breathing = breathing + 1 cv2.putText(frame, 'Breathing', (10, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 1, cv2.LINE_AA) cv2.imshow('Frame', frame) else: t = t + 1 if t > 20: if lab_stats[1:, 4].size > 0 and start == 1: t = 0 n_breathing = n_breathing + 1 cv2.putText(frame, 'Not Breathing', (10, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 1, cv2.LINE_AA) cv2.imshow('Frame', frame) else: breathing = breathing + 1 cv2.circle(frame, (cX1, cY1), red, (0, 255, 255), 3) cv2.circle(frame, (cX2, cY2), red, (0, 255, 255), 3) cv2.circle(frame, (cX3, cY3), red, (0, 255, 255), 3) # cv2.putText(frame, 'Breathing', (10, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 1, cv2.LINE_AA) cv2.imshow('Frame', frame) i = i + 1 previous_frame = current_frame k = cv2.waitKey(30) & 0xff if k == 27: break cap.release() cv2.destroyAllWindows()
# 파란색 기준값을 120으로 상한, 하한값 정하기 # 채도가 높은 파란색을 검출하기 때문에 HSV 색공간의 채도값을 # 높여 채도가 낮은 파란색을 제거, 테스트에선 70을 사용 lower_blue = (120 - 20, 70, 0) upper_blue = (120 + 20, 255, 255) img_mask = cv.inRange(img_hsv, lower_blue, upper_blue) # 모폴로지 연산을 사용하여 바이너리 이미지를 개선 kernel = cv.getStructuringElement(cv.MORPH_RECT, (11, 11)) img_mask = cv.morphologyEx(img_mask, cv.MORPH_CLOSE, kernel) # 컬러영상에서 파란색만 보여줌 img_result = cv.bitwise_and(img_frame, img_frame, mask=img_mask) nlabels, labels, stats, centroids = cv.connectedComponentsWithStats( img_mask) for i in range(nlabels): if i < 1: continue area = stats[i, cv.CC_STAT_AREA] center_x = int(centroids[i, 0]) center_y = int(centroids[i, 1]) left = stats[i, cv.CC_STAT_LEFT] top = stats[i, cv.CC_STAT_TOP] width = stats[i, cv.CC_STAT_WIDTH] height = stats[i, cv.CC_STAT_HEIGHT] # 영역의 크기가 10000 이상인 경우 다음과 같은 정보 표시 if area > 1000:
try: os.mkdir( "out" ) except: pass # def url_to_image(url): # resp = urllib.request.urlopen(url) # image = np.asarray(bytearray(resp.read()), dtype="uint8") # image = cv2.imdecode(image, cv2.IMREAD_GRAYSCALE) # return image # img = url_to_image("https://uc5204b69423c30e717ff6a61658.previews.dropboxusercontent.com/p/thumb/AAsy9MYUdbGP5iAo0-Mb-8TaZKpoyZMeGu6ctYkHRH9VG8P6rbVeADFOtqLDiuvWmd_kuBMTTCqAMCTDfJn_sIHZj2nHyiyO234exDVUpyGbTNpqtkGZigbNSNbfodaX8qn4kOdGPurkNl84ybtLloaM_VTmncfs0kVK7NUyfdJ88m-u7Vz133zP4X3BOOeBB_WGkJrCxoTVzpQIcmYr6mhothTvSTpL89eVCOotU_eVfSy5eJ7v9UF0ULgHYFhbqmxLNvUKhlP259_q8RKTmx5nzwEcgidguO80hycVN1Nl_U7aVjt5zeWj0rZzvxq3Qy55LTvClSWU4cvDy_bnbWKOE3XpA1TTyVWw9ZpHnzLHPSmlmNvAYh7bOS5lLuP95vGuH46TizZHL_CQ80lEFUx1tkPbd1ifRG-y7cPZwQAAtebkCn66BS9GbgzUvS7C_zN5kZJyalHCpG86w6jCzxYd/p.jpeg?fv_content=true&size_mode=5") files = os.listdir("input") index = 0 compIndex = 0 for f in files: index = index + 1 if f.endswith(".jpg") or f.endswith(".jpeg"): print ("working on " + str(index) + "/" + str(len(files)) + ": " + f) img = cv2.imread('input/' + f, cv2.IMREAD_COLOR) grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, bw_img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) bw_img = cv2.bitwise_not(bw_img[:, :, 1]) [num_labels, labels, stats, centroids] = cv2.connectedComponentsWithStats(bw_img, 4, cv2.CV_32S) for stat in stats: [x, y, w, h, area] = stat if w > 200 and h > 200 and w < 1000 and h < 1000: compIndex = compIndex + 1 cv2.imwrite("out/" + str(compIndex) + ".jpg", img[y:y+h, x:x+w])
def TrafficLight(ret2, src2, Traffic_Light): cnt = 0 # traffic============================================ Traffic_Light_ROI = src2[0:250, 0:340] img_hsv = cv2.cvtColor(Traffic_Light_ROI, cv2.COLOR_BGR2HSV) if Traffic_Light == True: # 파란불 찾기 모드일때 # 이거는 초록색(그냥 상수로 넣어도 된다) img_mask1 = cv2.inRange(img_hsv, (68, 30, 30), (78, 255, 255)) img_mask2 = cv2.inRange(img_hsv, (56, 30, 30), (54, 255, 255)) img_mask3 = cv2.inRange(img_hsv, (56, 30, 30), (68, 255, 255)) # img_mask1_big = cv.inRange(img_hsv_big, (68, 30, 30), (78, 255, 255)) # img_mask2_big = cv.inRange(img_hsv_big, (56, 30, 30), (54, 255, 255)) # img_mask3_big = cv.inRange(img_hsv_big, (56, 30, 30), (68, 255, 255)) else: # 빨간불 찾기 모드일때 img_mask1 = cv2.inRange(img_hsv, (140, 30, 30), (180, 255, 255)) img_mask2 = cv2.inRange(img_hsv, (1, 30, 30), (5, 255, 255)) img_mask3 = cv2.inRange(img_hsv, (100, 30, 30), (15, 255, 255)) # img_mask1_big = cv.inRange(img_hsv_big, (68, 30, 30), (78, 255, 255)) # img_mask2_big = cv.inRange(img_hsv_big, (56, 30, 30), (54, 255, 255)) # img_mask3_big = cv.inRange(img_hsv_big, (56, 30, 30), (68, 255, 255)) img_mask = img_mask1 | img_mask2 | img_mask3 kernel = np.ones((11, 11), np.uint8) img_mask = cv2.morphologyEx(img_mask, cv2.MORPH_OPEN, kernel) # 모폴로지-영상노이즈제거 img_mask = cv2.morphologyEx(img_mask, cv2.MORPH_CLOSE, kernel) img_result = cv2.bitwise_and(Traffic_Light_ROI, Traffic_Light_ROI, mask=img_mask) numOfLabels, img_label, stats, centroids = cv2.connectedComponentsWithStats( img_mask) for idx, centroid in enumerate(centroids): # enumerate는 리스트 값을 전달하는 기능 if stats[idx][0] == 0 and stats[idx][1] == 0: continue if np.any(np.isnan(centroid)): continue x, y, width, height, area = stats[idx] centerX, centerY = int(centroid[0]), int(centroid[1]) # print(centerX, centerY) if area > 50: # cv.circle(img_color, (centerX, centerY), 10, (0, 0, 255), 10) # cv.rectangle(img_color, (x, y), (x + width, y + height), (0, 0, 255)) cv2.circle(Traffic_Light_ROI, (centerX, centerY), 10, (0, 0, 255), 10) cv2.rectangle(Traffic_Light_ROI, (x, y), (x + width, y + height), (0, 0, 255)) if 0 < centroid[0] and centroid[0] <= 340 and centroid[ 0] != 169.5: # 인식된 색의 x좌표가 roi영역의 x축 안에있으면 if centroid[1] <= 250 and centroid[ 1] != 124.5: # 인식된 색의 y좌표가 roi영역의 y축 안에있으면 cnt += 1 print(cnt) if cnt >= 30: # 50되면 print("Flag Toggle") Traffic_Light = not Traffic_Light cnt = 0 else: cnt = 0 else: cnt = 0 return Traffic_Light
def ourapproach(model, connectivity, inputfile, num, name): blocks = [] img_i = cv2.imread(inputfile, 0) img_new = cv2.imread(inputfile, 0) list1 = [] kernalnew = np.ones((2, 4), np.uint8) kernalnew1 = np.ones((1, 1), np.uint8) output = counting_components(connectivity, inputfile) img_new = cv2.erode(img_new, kernalnew, iterations=25) for yf in range(0, 1000): img_new = cv2.erode(img_new, kernalnew, iterations=1) img_new = cv2.dilate(img_new, kernalnew1, iterations=1) binary_map1 = (img_new < 255).astype(np.uint8) output1 = cv2.connectedComponentsWithStats(binary_map1, connectivity, cv2.CV_32S)[0] if output > output1: output = output1 else: img_new = cv2.dilate(img_new, kernalnew1, iterations=2) cv2.imwrite("%s_layout.png" % inputfile, img_new) binary_map1 = (img_new < 200).astype(np.uint8) blocks.append( cv2.connectedComponentsWithStats(binary_map1, connectivity, cv2.CV_32S)[2][1:]) Ent = [] for t in range(1, len(blocks[0])): img_b = img_i[blocks[0][t][1]:blocks[0][t][1] + blocks[0][t][3], blocks[0][t][0]:blocks[0][t][0] + blocks[0][t][2]] for ii in range(len(img_b)): for jj in range(len(img_b[0])): if img_b[ii][jj] > 215: img_b[ii][jj] = 215 else: img_b[ii][jj] = img_b[ii][jj] img_x = img_b x1 = data_augmentation(img_x) try: X = [] Y = [] pred = [] label_count = [] for m in range(len(x1)): x2 = np.reshape(x1[m][0:-1], (-1, 100)) y = x1[m][-1] X.append(x2) Y.append(y) X = np.array(X) X1 = np.expand_dims(X, axis=3) y_pred = model.predict(X1) for r in range(len(y_pred)): label = np.argmax(y_pred[r]) pred.append(label) table = pred.count(2) image = pred.count(0) text = pred.count(1) math = pred.count(3) lined = pred.count(4) label_count = [image, text, table, math, lined] lab = label_count.index(max(label_count)) print(lab) if lab == 0: print('image') elif lab == 1: print('text') Entity = blockparasing(img_x) print(Entity) Ent.append(str(Entity)) Ent.append('\n') elif lab == 2: print('table') elif lab == 3: print('math') Entity = blockparasing(img_x) Ent.append(str(Entity)) Ent.append('\n') else: print('Lined') except: print('noise') return Ent
def ImageProcessor(unprocessed_frames, processed_frames, proc_complete, event_manager, n_calib): processing = False proc_complete.set() # preallocate memory for all arrays used in processing img_mean = np.zeros([h, w], dtype=np.float32) img_std = np.ones([h, w], dtype=np.float32) A = np.zeros([h, w], dtype=np.uint8) B = np.zeros([h, w], dtype=np.uint8) B_old = np.zeros([h, w], dtype=np.uint8) C = np.zeros([h, w], dtype=np.uint8) mean_1 = np.zeros([h, w], dtype=np.float32) mean_2 = np.zeros([h, w], dtype=np.float32) std_1 = np.zeros([h, w], dtype=np.float32) std_2 = np.zeros([h, w], dtype=np.float32) std_3 = np.zeros([h, w], dtype=np.float32) std_4 = np.zeros([h, w], dtype=np.float32) std_5 = np.zeros([h, w], dtype=np.float32) std_6 = np.zeros([h, w], dtype=np.float32) B_1_std = np.zeros([h, w], dtype=np.float32) B_1_mean = np.zeros([h, w], dtype=np.float32) B_greater = np.zeros([h, w], dtype=np.uint8) B_2_mean = np.zeros([h, w], dtype=np.float32) B_less = np.zeros([h, w], dtype=np.uint8) ########## FOR TESTING ############## img_array = [] C_array = [] # std_data = np.zeros([h,w],dtype=np.float32) # mean_data = np.zeros([h,w],dtype=np.float32) save_arr = False y_data = np.zeros((h, w)) img_temp = np.zeros((3, h, w)) C_temp = np.zeros((3, h, w)) temp_img = np.zeros((h, w)) ########## FOR TESTING ############## last_n_frame = 0 p = c.LEARNING_RATE time_cumulative = 0 total_time = 0 total_frames = 0 while True: time.sleep(1E-4) try: if event_manager.shutdown.is_set(): proc_complete.set() return # get the frames from queue n_frame, n_frame_2, frame_buf = unprocessed_frames.get_nowait() # y_data is a numpy array hxw with 8 bit greyscale brightness values y_data = np.frombuffer(frame_buf, dtype=np.uint8, count=w * h).reshape( (h, w)).astype(np.float32) # every 3 frames update the background if n_frame_2 > (last_n_frame + c.BACKGROUND_RATE ) and not event_manager.event_change.is_set(): last_n_frame = n_frame_2 # img_mean = (1 - p) * img_mean + p * y_data # calculate mean np.multiply(1 - p, img_mean, out=mean_1) np.multiply(p, y_data, out=mean_2) np.add(mean_1, mean_2, out=img_mean) # img_std = np.sqrt((1 - p) * (img_std ** 2) + p * ((y_data - img_mean) ** 2)) # calculate std deviation np.square(img_std, out=std_1) np.multiply(1 - p, std_1, out=std_2) np.subtract(y_data, img_mean, out=std_3) np.square(std_3, out=std_4) np.multiply(p, std_4, out=std_5) np.add(std_2, std_5, out=std_6) np.sqrt(std_6, out=img_std) if not proc_complete.is_set() and n_frame > -1: mean_data = img_mean std_data = img_std start = time.time_ns() B_old = np.copy(B) # B = np.logical_or((y_data > (img_mean + 2*img_std)), # (y_data < (img_mean - 2*img_std))) # foreground new np.multiply(img_std, 3, out=B_1_std) np.add(B_1_std, img_mean, out=B_1_mean) B_greater = np.greater(y_data, B_1_mean) np.subtract(img_mean, B_1_std, out=B_2_mean) B_less = np.less(y_data, B_2_mean) B = np.logical_or(B_greater, B_less) A = np.invert( np.logical_and(B_old, B) ) # difference between prev foreground and new foreground C = np.logical_and( A, B) # different from previous frame and part of new frame C = 255 * C.astype(np.uint8) C = cv2.filter2D(C, ddepth=-1, kernel=kernel4) C[C < c.LPF_THRESH] = 0 C[C >= c.LPF_THRESH] = 255 n_features_cv, labels_cv, stats_cv, centroids_cv = cv2.connectedComponentsWithStats( C, connectivity=4) label_mask_cv = np.logical_and( stats_cv[:, cv2.CC_STAT_AREA] > 2, stats_cv[:, cv2.CC_STAT_AREA] < 10000) ball_candidates = np.concatenate( (stats_cv[label_mask_cv, 2:], centroids_cv[label_mask_cv]), axis=1) # sort ball candidates by size and keep the top 100 ball_candidates = ball_candidates[ ball_candidates[:, c.SIZE].argsort()[::-1][:c.N_OBJECTS]] processed_frames.put((n_frame, ball_candidates)) ########## FOR TESTING ############## C_temp = cv2.cvtColor(C, cv2.COLOR_GRAY2RGB) img_temp = cv2.cvtColor(y_data, cv2.COLOR_GRAY2RGB) ball_candidates = ball_candidates.astype(int) for ball in ball_candidates: cv2.drawMarker(C_temp, (ball[c.X_COORD], ball[c.Y_COORD]), (0, 0, 255), cv2.MARKER_CROSS, thickness=2, markerSize=10) cv2.drawMarker(img_temp, (ball[c.X_COORD], ball[c.Y_COORD]), (0, 0, 255), cv2.MARKER_CROSS, thickness=2, markerSize=10) save_arr = True img_array.append((n_frame, y_data)) C_array.append(C_temp) total_time += (time.time_ns() - start) total_frames += 1 ########## FOR TESTING ############## elif event_manager.record_stream.is_set() and n_frame > -1: if n_frame % n_calib.value == 0: processed_frames.put((n_frame, y_data)) except queue.Empty: if not event_manager.recording.is_set( ) and unprocessed_frames.qsize( ) == 0: # if the recording has finished proc_complete.set() # set the proc_complete event ######### FOR TESTING ############## if total_frames > 0: print((total_time / total_frames) / 1E6) total_frames = 0 total_time = 0 if img_array is not None and save_arr: for i, img in enumerate(img_array): frame, data = img os.chdir(c.IMG_P) cv2.imwrite(f"{frame:04d}.png", data) cv2.imwrite(f"C{frame:04d}.png", C_array[i]) os.chdir(c.DATA_P) np.save('img_mean', mean_data) np.save('img_std', std_data) os.chdir(c.ROOT_P) img_array = [] C_array = [] save_arr = False
mat2gray = cv2.normalize(A, out, 1.0, 0.0, cv2.NORM_MINMAX) dynamic= dst - mat2gray window_size = 15 thresh_niblack = segment.threshold_niblack(dynamic, window_size=window_size, k=0.4) binary_niblack = dynamic >= thresh_niblack indices = binary_niblack.astype(np.uint8) indices*=255 #cv2.imshow('Indices',indices) # inverse = cv2.bitwise_not(indices) #cv2.imshow('dynamic thres',inverse) nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(inverse, connectivity=4) sizes = stats[1:, -1]; nb_components = nb_components - 1 min_size = 350 img6 = np.zeros((output.shape)) for i in range(0, nb_components): if sizes[i] > min_size: img6[output == i + 1] = 255 img6= np.uint8(img6) #cv2.imshow('bwareopen',img6) #mask gammaroi= np.array(255*(gray/255)**0.9,dtype='uint8') gma = cv2.hconcat([gammaroi]) retval, mask_threshold = cv2.threshold(gma, 68, 500, cv2.THRESH_BINARY) inverse_maskbang = cv2.bitwise_not(mask_threshold) kernel3 = np.ones((5,5),np.uint8)
marker[:, -1] = 255 marker_0 = marker.copy() # 形态学重建 SE = cv2.getStructuringElement(shape=cv2.MORPH_CROSS, ksize=(3, 3)) while True: marker_pre = marker dilation = cv2.dilate(marker, kernel=SE) marker = np.min((dilation, mask), axis=0) if (marker_pre == marker).all(): break dst = 255 - marker cv2.imwrite('picture2.jpg', dst) # 显示 num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats( dst, connectivity=8) #删除小的连通域 # 查看各个返回值 # 连通域数量 #print('num_labels = ',num_labels) # 连通域的信息:对应各个轮廓的x、y、width、height和面积 #print('stats = ',stats) # 连通域的中心点 #print('centroids = ',centroids) # 每一个像素的标签1、2、3.。。,同一个连通域的标签是一致的 #print('labels = ',labels) # 不同的连通域赋予不同的颜色 output = np.zeros((img.shape[0], img.shape[1], 3), np.uint8) for i in range(1, num_labels):
def segment_foreground( frame: np.ndarray, foreground_close_struct_element, foreground_dilate_struct_element, threshold_fn: Callable[[np.ndarray], int], is_foreground_lighter_than_background: bool, ): """ Processes a frame to isolate the object of interest (worm) from the background :param frame: image to process :param foreground_close_struct_element: morphological element to close holes in the foreground mask :param foreground_dilate_struct_element: morphological element to expand the foreground mask :param threshold_fn: function that will return the threshold to separate foreground from background in a frame :param is_foreground_lighter_than_background: set to True if the foreground object of interest is lighter (pixel values are on average higher) than the background :return: segmentation mask with values of 1 for the worm object and 0 for the background, and average value of the background pixels """ # find the threshold to separate foreground from background background_threshold = threshold_fn(frame) # use the threshold to deduce background and foreground masks, fill in holes foreground_mask = (frame > 0).astype( np.uint8) * (frame < background_threshold).astype(np.uint8) foreground_mask = cv2.morphologyEx(foreground_mask, cv2.MORPH_CLOSE, foreground_close_struct_element) background_mask = (((frame > 0).astype(np.uint8) - foreground_mask) > 0).astype(np.uint8) # invert foreground and background masks if the foreground is lighter than the background if is_foreground_lighter_than_background: foreground_mask, background_mask = background_mask, foreground_mask # calculate the average background color background_values = frame[background_mask.astype(bool)] background_color = int( np.mean(background_values)) if len(background_values) > 0 else 0 background_color = frame.dtype.type(background_color) # process the foreground mask to eliminate non worm objects # use connected components to find blobs, but focus on the center of the image to find the biggest # modify foreground_mask to only show the worm object nb_labels, labels, stats, _ = cv2.connectedComponentsWithStats( foreground_mask) labels_crop_size = int(_CROP_PERCENT * max(foreground_mask.shape)) labels_cropped = labels[labels_crop_size:foreground_mask.shape[0] - labels_crop_size, labels_crop_size:foreground_mask.shape[1] - labels_crop_size, ] if nb_labels == 1: foreground_mask.fill(0) foreground_objects_sizes = [ len(np.where(labels_cropped == l)[0]) for l in range(1, nb_labels) ] if len(foreground_objects_sizes) > 0: biggest_blob_label = np.argmax(foreground_objects_sizes) + 1 foreground_mask[labels != biggest_blob_label] = 0 # add a little padding to the foreground mask foreground_mask = cv2.dilate(foreground_mask, foreground_dilate_struct_element) return foreground_mask, background_color
def getMagnification(frame: np.ndarray, debug=False) -> float: '''Function uses ML OCR to determine the magnification of the frame from the drone video. Parameters ---------- filename : str filename of the frame to determine the magnification from. debug : bool, optional If True then returns list of images and their classifications for debug purposes. Returns ------- magnification : float The determined magnification level of the drone video. ''' from setting import model if debug: import matplotlib.pyplot as plt fig, axs = plt.subplots(1, 3) # Open image and convert to grayscale array = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # array = img array = array[92:130, 24:140] # Threshold, dilate and then crop to ROI. ret2, thresh = cv2.threshold(array, 200, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) thresh = label(thresh) thresh = remove_small_objects(thresh, 100) # convert image back to binary and uint8 type thresh = np.where(thresh > 0, 255, 0) thresh = np.array(thresh, "uint8") if debug: axs[0].imshow(array) if np.mean(thresh) > 100.: ret, thresh = cv2.threshold(array, 200, 255, cv2.THRESH_BINARY) kernel = np.ones((2, 2), np.uint8) thresh = cv2.dilate(thresh, kernel, iterations=1) thresh = label(thresh) thresh = remove_small_objects(thresh, 100) thresh = np.where(thresh > 0, 255, 0) array = np.array(thresh, "uint8") else: fraction = np.sum(thresh/255)/(thresh.shape[0]*thresh.shape[1]) if fraction > 0.2: array = np.where(array < 50, 255, array) ret2, thresh = cv2.threshold(array, 210, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) thresh = label(thresh) thresh = remove_small_objects(thresh, 100) # convert image back to binary and uint8 type thresh = np.where(thresh > 0, 255, 0) thresh = np.array(thresh, "uint8") kernel = np.ones((2, 2), np.uint8) thresh = cv2.erode(thresh, kernel, iterations=1) if debug: axs[1].imshow(thresh) array = thresh else: kernel = np.ones((2, 2), np.uint8) array = thresh array = cv2.dilate(thresh, kernel, iterations=1) # label again, this time with stats calculated output = cv2.connectedComponentsWithStats(array, 8, cv2.CV_32S) nlabels = output[0] # number of labels array = output[1] # Labeled image stats = output[2] # List of stats for each label labels = [] digits = [] if debug: axs[2].imshow(array) # Sort labels so that they are processed in left to right order s = stats[1:, cv2.CC_STAT_LEFT] labelOrder = sorted(range(len(s)), key=lambda k: s[k]) # classify digits for i in labelOrder: digits.append(_processLabels(array, stats, i+1)) lab = model.predict_classes(digits[-1].reshape(1, 28, 28, 1).astype('float32')/255) labels.append(lab) if debug: print(labels) plt.show() # if method fails just return 1.0 magnification if len(labels) == 1: return 1.0 # format and return magnification level first = labels[0] second = labels[1] if len(labels) > 2: if int(str(first[0])+str(second[0])) < 20.: if len(labels) == 3: third = None else: third = labels[2] else: third = None else: third = None if third: magnification = float(f"{first[0]}{second[0]}.{third[0]}") else: magnification = float(f"{first[0]}.{second[0]}") return magnification
def apply_block_extraction_on_image(image, scale, src, dst): #image should be black and white if len(image.shape) == 3: image = cv2.cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) org = np.copy(image) #binarize image _, image = cv2.threshold(image, 250, 255, cv2.THRESH_BINARY) #remove black boxes #image = remove_black_boxes_on_image(image) #remove small connected components nocc = remove_small(image, int(30 * scale)) inverted = invert(nocc) width = int(15 * scale) #erode to get rid of noise kernel_b = np.ones((int(3 * scale), int(3 * scale)), np.uint8) result_er = cv2.erode(inverted, kernel_b) #remove small pixels result_er = remove_small(result_er, int(5 * scale), invert_img=False) #Dilate vertically to link the accents kernel_v = np.ones((width, 1), np.uint8) result_v = cv2.dilate(result_er, kernel_v) # dilate horizontally to link the characters all together kernel_h = np.ones((1, width), np.uint8) result_h = cv2.dilate(result_v, kernel_h) mask = result_h spotted = np.copy(image) spotted[mask == 0] = 255 #keep big enough components mask = remove_small(mask, int(500 * scale), invert_img=False) image[mask == 0] = 255 # define the ratio for each field boxes = dict() boxes["interest_roi"] = np.array([[370, 325], [483, 407]]) #address block is interest_roi boxes = scale_boxes(boxes, scale) fields = define_field(src, boxes) #extract component part to_keep = np.copy(mask) nb_components, output, stats, centroids = cv2.connectedComponentsWithStats( to_keep, connectivity=4) indices = [i for i, f in enumerate(fields) if f == "interest_roi"] if 'interest_roi' in fields: msg = 'found_kp' #extract component part best_tl_x = 0 best_tl_y = 0 best_br_x = 0 best_br_y = 0 for a, i in enumerate(indices): #compute block box p1, p2 = crop_box(src[i], dst[i], boxes) if a == 0: best_tl_x = p1[0] best_tl_y = p1[1] best_br_x = p2[0] best_br_y = p2[1] #keep combo of largest box if p1[0] < best_tl_x: best_tl_x = p1[0] if p1[1] < best_tl_y: best_tl_y = p1[1] if p2[0] > best_br_x: best_br_x = p2[0] if p2[1] > best_br_y: best_br_y = p2[1] #crop the box cropped = org[best_tl_y:best_br_y, best_tl_x:best_br_x] #the ratio is always good return cropped, True else: #choose connected component with closest centroid centroids = centroids[1:] approx_center = np.array([ int(image.shape[1] * 0.62 * scale), int(image.shape[0] * 0.81 * scale) ]) distances = [ np.linalg.norm(np.array(x) - approx_center) for x in centroids ] if len(distances) == 0: return None index = np.argsort(distances)[0] + 1 #define bounding box of component index = index left = stats[index, cv2.CC_STAT_LEFT] top = stats[index, cv2.CC_STAT_TOP] width = stats[index, cv2.CC_STAT_WIDTH] height = stats[index, cv2.CC_STAT_HEIGHT] comp_roi = org[top:(top + height), left:(left + width)] return comp_roi, size_ok(comp_roi.shape, image.shape)
) # konwersja typu logicznego na liczbowy I_B = I_B * 255 # zamiana zakresu z {0, 1} na {0, 255} (poprawne wyświetlanie) I_B = I_B.astype( np.uint8) # rzutowanie zmiennych na typ całkowity uint8 I_GT = 1 * (I_GT == 255) # konwersja typu logicznego na liczbowy I_GT = I_GT * 255 # zamiana zakresu z {0, 1} na {0, 255} (poprawne wyświetlanie) I_GT = I_GT.astype( np.uint8) # rzutowanie zmiennych na typ całkowity uint8 I_B = cv.medianBlur(I_B, 3) # operacje morfologiczne na analizowanym obrazie I_B = cv.erode(I_B, kernel, iterations=1) I_B = cv.dilate(I_B, kernel, iterations=1) retval, labels, stats, centroids = cv.connectedComponentsWithStats( I_B) # rysowanie prostokąta wokół największego ruchomego obiektu I_VIS = I.copy() if stats.shape[0] > 1: tab = stats[1:, 4] pi = np.argmax(tab) pi = pi + 1 cv.rectangle( I_VIS, (stats[pi, 0], stats[pi, 1]), (stats[pi, 0] + stats[pi, 2], stats[pi, 1] + stats[pi, 3]), (255, 0, 0), 2) cv.putText(I_VIS, "%f" % stats[pi, 4], (stats[pi, 0], stats[pi, 1]), cv.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0)) cv.putText(
interpolation=cv2.INTER_AREA) img_hsv = cv2.cvtColor(img_color, cv2.COLOR_BGR2HSV) img_mask1 = cv2.inRange(img_hsv, lower_blue1, upper_blue1) img_mask2 = cv2.inRange(img_hsv, lower_blue2, upper_blue2) img_mask3 = cv2.inRange(img_hsv, lower_blue3, upper_blue3) img_mask = img_mask1 | img_mask2 | img_mask3 kernel = np.ones((3, 3), np.uint8) img_mask = cv2.morphologyEx(img_mask, cv2.MORPH_OPEN, kernel) img_mask = cv2.morphologyEx(img_mask, cv2.MORPH_CLOSE, kernel) img_result = cv2.bitwise_and(img_color, img_color, mask=img_mask) numOfLabels, img_label, stats, centroids = cv2.connectedComponentsWithStats( img_mask) for idx, centroid in enumerate(centroids): if stats[idx][0] == 0 and stats[idx][1] == 0: continue if np.any(np.isnan(centroid)): continue x, y, width, height, area = stats[idx] centerX, centerY = int(centroid[0]), int(centroid[1]) if area > 75: cv2.circle(img_color, (centerX, centerY), 10, (0, 0, 255), 10) cv2.rectangle(img_color, (x, y), (x + width, y + height), (0, 0, 255))
def white_out_borders(scaledimg): axis0limit = [] axis0limitindexnp = [] axis0limitindexflat = [] axis1limit = [] axis1limitindexnp = [] axis1limitindexflat = [] toplistlimit = [] bottomlistlimit = [] rightlistlimit = [] leftlistlimit = [] scaledimg_borders = scaledimg.copy() scaledimg_borders_redchannel = scaledimg_borders[:, :, 2] rows, cols = scaledimg_borders_redchannel.shape image_data = np.asarray(scaledimg_borders_redchannel) rpxvalue = [] for i in range(rows): for j in range(cols): rpxvalue.append((image_data[i, j])) rimage_aslist = list(rpxvalue[i:i + cols] for i in range(0, len(rpxvalue), cols)) rimage_asarray = np.asarray(rimage_aslist) # Get vertical standard deviation rgbsta0 = np.std(rimage_asarray, axis=0) # Get horizontal standard deviation rgbsta1 = np.std(rimage_asarray, axis=1) ''' plt.figure() plt.subplot(211) plt.title('S.d along axis 0') plt.ylabel('S.d.') plt.xlabel('Axis') plt.plot(rgbsta0, 'r') plt.subplot(212) plt.title('S.d along axis 1') plt.ylabel('S.d.') plt.xlabel('Axis') plt.plot(rgbsta1, 'r') plt.show() ''' sdthreshold = 20 for i in range(len(rgbsta0)): if rgbsta0[i] < sdthreshold: axis0limit.append(rgbsta0[i]) axis0limitindexnp.append(np.where(rgbsta0 == rgbsta0[i])) for i in range(len(axis0limitindexnp)): axis0limitindexflat.append(axis0limitindexnp[i][0][0]) for i in range(len(rgbsta1)): if rgbsta1[i] < sdthreshold: axis1limit.append(rgbsta1[i]) axis1limitindexnp.append(np.where(rgbsta1 == rgbsta1[i])) for i in range(len(axis1limitindexnp)): axis1limitindexflat.append(axis1limitindexnp[i][0][0]) splitlisthresholdrows = rows / 4 splitlisthresholdcols = cols / 4 for i in axis0limitindexflat: if (i < splitlisthresholdrows) & (i <= 0.05 * rows): leftlistlimit.append(i) elif (i > splitlisthresholdrows) & (i >= 0.95 * rows): rightlistlimit.append(i) for i in axis1limitindexflat: if (i < splitlisthresholdcols) & (i <= 0.05 * cols): toplistlimit.append(i) elif (i > splitlisthresholdcols) & (i >= 0.95 * cols): bottomlistlimit.append(i) try: toplimit = max(toplistlimit) except ValueError: toplimit = int(0.02 * rows) try: bottomlimit = min(bottomlistlimit) except ValueError: bottomlimit = int(0.98 * rows) try: leftlimit = max(leftlistlimit) except ValueError: leftlimit = int(0.02 * cols) try: rightlimit = min(rightlistlimit) except ValueError: rightlimit = int(0.98 * cols) ### PART 2 ### cornerstoplist = [] cornerstoplistx = [] cornerstoplisty = [] cornersbottomlist = [] cornersbottomlistx = [] cornersbottomlisty = [] cornersleftlist = [] cornersleftlistx = [] cornersleftlisty = [] cornersrightlist = [] cornersrightlistx = [] cornersrightlisty = [] scaledimg_borders_2 = scaledimg.copy() mediansmoothedimg_borders = cv2.medianBlur(scaledimg_borders_2, 3) grayimg_borders = cv2.cvtColor(mediansmoothedimg_borders, cv2.COLOR_BGR2GRAY) v_edges = cv2.Sobel(grayimg_borders, cv2.CV_16S, 1, 0, ksize=3, scale=1, delta=0, borderType=cv2.BORDER_DEFAULT) h_edges = cv2.Sobel(grayimg_borders, cv2.CV_16S, 0, 1, ksize=3, scale=1, delta=0, borderType=cv2.BORDER_DEFAULT) abs_grad_x = cv2.convertScaleAbs(v_edges) abs_grad_y = cv2.convertScaleAbs(h_edges) mask = np.zeros(grayimg_borders.shape, dtype=np.uint8) linewidth = ((grayimg_borders.shape[0] + grayimg_borders.shape[1])) / 50 ## Detect the vertical edges ## magv = np.abs(v_edges) magv2 = (255 * magv / np.max(magv)).astype(np.uint8) _, mag2 = cv2.threshold(magv2, 15, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(mag2.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for contour in contours: _, _, w, h = cv2.boundingRect(contour) if h > grayimg_borders.shape[0] / 4 and w < linewidth: cv2.drawContours(mask, [contour], -1, 255, -1) ## Detect the horizontal edges ## magh = np.abs(h_edges) magh2 = (255 * magh / np.max(magh)).astype(np.uint8) _, mag2 = cv2.threshold(magh2, 15, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(mag2.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for contour in contours: _, _, w, h = cv2.boundingRect(contour) if w > grayimg_borders.shape[1] / 4 and h < linewidth: cv2.drawContours(mask, [contour], -1, 255, -1) kerneldilate = np.ones((5, 5), np.uint8) dilation = cv2.dilate(mask, kerneldilate, 10) #diltr = cv2.resize(dilation, (400,400)) #cv2.imshow('corners', diltr) dst = cv2.cornerHarris(dilation, 2, 3, 0.001) ret, dst = cv2.threshold(dst, 0.01 * dst.max(), 255, 0) dst = np.uint8(dst) ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst) criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001) corners = cv2.cornerSubPix(dst, np.float32(centroids), (5, 5), (-1, -1), criteria) upperrowlimit = int(rows * (5 / 100)) lowerrowlimit = int(rows * (95 / 100)) leftcollimit = int(cols * (5 / 100)) rightcollimit = int(cols * (95 / 100)) heightpadding = int(rows) - 100 widthpadding = int(cols) - 100 for i in range(len(corners)): if ((corners[i][1] <= upperrowlimit) & (corners[i][1] >= 10)): cornerstoplist.append((int(corners[i][0]), int(corners[i][1]))) cornerstoplistx.append((int(corners[i][0]))) cornerstoplisty.append((int(corners[i][1]))) try: maxcornerstoplist = int(max(cornerstoplisty)) except statistics.StatisticsError: maxcornerstoplist = 0.02 * rows except ValueError: maxcornerstoplist = 0.02 * rows for i in range(len(corners)): if ((corners[i][1] >= lowerrowlimit) & (corners[i][1] <= heightpadding)): cornersbottomlist.append((int(corners[i][0]), int(corners[i][1]))) cornersbottomlistx.append((int(corners[i][0]))) cornersbottomlisty.append((int(corners[i][1]))) try: mincornersbottomlist = int(min(cornersbottomlisty)) except statistics.StatisticsError: mincornersbottomlist = 0.98 * rows except ValueError: mincornersbottomlist = 0.02 * rows for i in range(len(corners)): if ((corners[i][0] <= leftcollimit) & (corners[i][0] >= 10)): cornersleftlist.append((int(corners[i][0]), int(corners[i][1]))) cornersleftlistx.append((int(corners[i][0]))) cornersleftlisty.append((int(corners[i][1]))) try: meancornersleftlist = int(statistics.mean(cornersleftlistx)) except statistics.StatisticsError: meancornersleftlist = 0.02 * cols except ValueError: meancornersleftlist = 0.02 * cols for i in range(len(corners)): if ((corners[i][0] >= rightcollimit) & (corners[i][0] <= widthpadding)): cornersrightlist.append((int(corners[i][0]), int(corners[i][1]))) cornersrightlistx.append((int(corners[i][0]))) cornersrightlisty.append((int(corners[i][1]))) try: meancornersrightlist = int(statistics.mean(cornersrightlistx)) except statistics.StatisticsError: meancornersrightlist = 0.98 * cols except ValueError: meancornersrightlist = 0.98 * cols topborder = int(max(toplimit, maxcornerstoplist)) bottomborder = int(min(bottomlimit, mincornersbottomlist)) leftborder = int(max(leftlimit, meancornersleftlist)) rightborder = int(min(rightlimit, meancornersrightlist)) whitenedbordersimg = scaledimg.copy() topblank = 255 * np.ones(shape=[topborder, cols, 3], dtype=np.uint8) bottomblank = 255 * np.ones(shape=[rows - bottomborder, cols, 3], dtype=np.uint8) leftblank = 255 * np.ones(shape=[rows, leftborder, 3], dtype=np.uint8) rightblank = 255 * np.ones(shape=[rows, cols - rightborder, 3], dtype=np.uint8) whitenedbordersimg[0:topborder, 0:cols] = topblank whitenedbordersimg[bottomborder:rows] = bottomblank whitenedbordersimg[0:cols, 0:leftborder] = leftblank whitenedbordersimg[0:rows, rightborder:cols] = rightblank return whitenedbordersimg
def centered_crop(self, image, thresh): #output = cv2.connectedComponentsWithStats(thresh, self.connectivity, cv2.CV_32S) #nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(binimage) nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats( thresh, self.connectivity, cv2.CV_32S) # print("output[2] = ", output[2]) # print("\n") # in general, almost allways thera two elements. idx_global = 1 # but, if there are more than 2, we have to find who has the major amount. if stats.shape[0] > 2: for idx_tmp in range(1, stats.shape[0]): if stats[idx_tmp, 4] > stats[idx_global, 4]: idx_global = idx_tmp # output[2] # x y w h amount px # 0 [ 0 0 1920 1080 1816041] <=== corresponds to the whole image # 1 [313 121 660 930 257558] # 2 [357 870 1 1 1] # bounding box x = stats[idx_global, 0] y = stats[idx_global, 1] w = stats[idx_global, 2] h = stats[idx_global, 3] # centroid x_center = centroids[idx_global, 0] y_center = centroids[idx_global, 1] #print("centroid({}, {})".format(int(x_center), int(y_center))) # top left corner of the crop x1 = int(x_center) - (self.width // 2) y1 = int(y_center) - (self.high // 2) if 0 <= x1 and 0 <= y1 and (x1 + self.width) <= stats[0, 2] and ( y1 + self.high) <= stats[0, 4]: #print(">> crop inside the image!!!") crop_thesh = thresh[y1:y1 + self.high, x1:x1 + self.width] crop_image = image[y1:y1 + self.high, x1:x1 + self.width] # erosion with SE = (width, high) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (self.width, self.high)) #kernel = np.ones((self.width, self.high), np.uint8) erosion = cv2.erode(crop_thesh, kernel, iterations=1) nlabels2, labels2, stats2, centroids2 = cv2.connectedComponentsWithStats( erosion, self.connectivity, cv2.CV_32S) #print(stats.shape) #sys.stdout.flush() #print(stats2) #sys.stdout.flush() if stats2.shape[0] == 2 and stats2[1, 0] == 0 and stats2[1, 1] == 0 and stats2[1, 2] == self.width and \ stats2[1, 3] == self.high and stats2[1, 4] == (self.width * self.high): #return True, crop_thesh[0:self.high, 0:self.width]*8 return True, crop_image[0:self.high, 0:self.width], crop_thesh[0:self.high, 0:self.width] #return True, image[y1:y1+self.high, x1:x1+self.width] return False, image[y:y + h, x:x + w], thresh[y:y + h, x:x + w]
def make(self, cf): if not os.path.exists(cf.bbox_output_path): os.makedirs(cf.bbox_output_path) images_stats = [] files_list = [] [files_list.append(os.path.splitext(name)) for name in self.X_original] for name in files_list: #print(name[0]) image = cv2.imread(os.path.join(cf.dataset_images_path, name[0] + name[1]), flags=cv2.IMREAD_COLOR) mask = cv2.imread( os.path.join(cf.dataset_mask_directory, name[0] + self.suffix), cv2.IMREAD_GRAYSCALE) ret, thresh = cv2.threshold(mask, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) stats = np.zeros([], dtype="uint8") centroid = np.array([]) output = cv2.connectedComponentsWithStats(thresh, self.connectivity, cv2.CV_32S) #print("output[2] = ", output[2]) #print("\n") # in general, almost allways thera two elements. idx_global = 1 # but, if there are more than 2, we have to find who has the major amount. if output[2].shape[0] > 2: for idx_tmp in range(1, output[2].shape[0]): if output[2][idx_tmp, 4] > output[2][idx_global, 4]: idx_global = idx_tmp # output[2] # x y w h amount px # 0 [ 0 0 1920 1080 1816041] <=== corresponds to the whole image # 1 [313 121 660 930 257558] # 2 [357 870 1 1 1] x = output[2][idx_global, 0] y = output[2][idx_global, 1] w = output[2][idx_global, 2] h = output[2][idx_global, 3] roi = image[y:y + h, x:x + w] print("Saving image: ", name[0]) cv2.imwrite(os.path.join(cf.bbox_output_path, name[0] + name[1]), roi) images_stats.append(output[2][idx_global]) # Save information of each image using idx_global (to be able to compute the mean size, max/min size.) np.save(os.path.join(cf.bbox_output_path, "images_stats"), np.array(images_stats))