def largest_connected_component(image): image = image.astype('uint8') # outputs labelled image, statistics and centroid for each label nb_components, output, stats, centroids = cv2.connectedComponentsWithStats( image, connectivity=8) sizes = stats[:, -1] if (len(sizes) <= 1): blank_image = np.zeros(image.shape) blank_image.fill(255) return blank_image max_label = 1 # Start from component 1 (not 0) because we want to leave out the background max_size = sizes[1] for i in range(2, nb_components): if sizes[i] > max_size: max_label = i max_size = sizes[i] img2 = np.zeros(output.shape) img2.fill(255) img2[output == max_label] = 0 return img2
def connectedComponents(binarized_img, connectivity = 8, ltype = cv2.CV_32S): output = cv2.connectedComponentsWithStats(binarized_img, connectivity, cv2.CV_32S) num_labels = output[0] labels = output[1] stats = output[2] centroids = output[3] return [num_labels, labels, stats, centroids]
def get_corners(img, param1=2, param2=3, param3=0.04): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = np.float32(gray) dst = cv2.cornerHarris(gray, param1, param2, param3) ret, dst = cv2.threshold(dst, 0.1 * 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(gray, np.float32(centroids), (5, 5), (-1, -1), criteria) return corners
def get_multi_match(image, needle, thresh): """在image中搜索多个needle的位置 重合的部分返回重合部分中心对应的坐标 """ match = get_all_match(image, needle) h, w = needle.shape[:2] # 模拟填充所有找到的匹配位置 draw = np.zeros(image.shape[:2], dtype="uint8") h, w = needle.shape[:2] for y, x in zip(*np.where(match < thresh)): cv.rectangle(draw, (x, y), (x + w, y + h), 255, -1) # 连通域分析 _, _, _, centroids = cv.connectedComponentsWithStats(draw.astype("uint8")) # 删去背景连通域 centroids = centroids[1:] # 中心坐标转化为左上角坐标 centroids[:, 0] -= w / 2 centroids[:, 1] -= h / 2 # 将数值转化为int型 return centroids.round().astype("int")
def apply_threshold(self): height, width, bytes_per_component = self.image.shape bytes_per_line = 3 * width self.threshold_image = np.zeros(self.image.shape, np.uint8) cv2.threshold(self.light_removed_image, 50, 255, cv2.THRESH_BINARY, self.threshold_image) demo_utils.show_cvimage_to_label(self.threshold_image, self.threshold_label) imgray = cv2.cvtColor(self.threshold_image, cv2.COLOR_BGR2GRAY) result = cv2.connectedComponentsWithStats(imgray) # cv2.CC_STAT_AREA print(" %d objects found" % result[0]) num_labels = result[0] # The second cell is the label matrix labels = result[1] stats = result[2] controlids = result[3] output = np.zeros(self.image.shape, np.uint8) random.seed() font = cv2.FONT_HERSHEY_SIMPLEX # org org = (50, 50) # fontScale fontScale = 0.5 # Blue color in BGR color1 = (255, 0, 0) # Line thickness of 2 px thickness = 1 outputed = False for i in range(1, num_labels): area = stats[i][cv2.CC_STAT_AREA] if area > 10: print("object:%d with area %d" % (i, area)) mask = labels == i color = (random.randint(40, 220), random.randint(40, 220), random.randint(40, 220)) # np.putmask(output, mask, [color]) output[mask] = color # Using cv2.putText() method # if not outputed: print(controlids[i]) org = controlids[i].astype(int) output = cv2.putText(output, "area: %d" % (area), tuple(org), font, fontScale, color, thickness) # outputed = True # cv2.putText(output, "area %d" % (area), tuple(controlids[i]), cv2.FONT_HERSHEY_COMPLEX,int(6) , color) demo_utils.show_cvimage_to_label(output, self.segment_label)
def cloud_shadow_detection(self, solz, sola, vector=None, cloud_height=500.0, model_fn=None, pixel_size=10.0): if self.sensor == 'S2A': blue_fn = [item for item in self.rhot_fns if 'rhot_492' in item][0] green_fn = [item for item in self.rhot_fns if 'rhot_560' in item][0] red_fn = [item for item in self.rhot_fns if 'rhot_665' in item][0] nir_fn = [item for item in self.rhot_fns if 'rhot_833' in item][0] swir1_fn = [item for item in self.rhot_fns if 'rhot_1614' in item][0] swir2_fn = [item for item in self.rhot_fns if 'rhot_2202' in item][0] cirrus_fn = [ item for item in self.rhot_fns if 'rhot_1373' in item ][0] else: blue_fn = [item for item in self.rhot_fns if 'rhot_492' in item][0] green_fn = [item for item in self.rhot_fns if 'rhot_559' in item][0] red_fn = [item for item in self.rhot_fns if 'rhot_665' in item][0] nir_fn = [item for item in self.rhot_fns if 'rhot_833' in item][0] swir1_fn = [item for item in self.rhot_fns if 'rhot_1610' in item][0] swir2_fn = [item for item in self.rhot_fns if 'rhot_2186' in item][0] cirrus_fn = [ item for item in self.rhot_fns if 'rhot_1377' in item ][0] blue = utils.band_math([blue_fn], 'B1') green = utils.band_math([green_fn], 'B1') red = utils.band_math([red_fn], 'B1') ndsi = utils.band_math([green_fn, swir1_fn], '(B1-B2)/(B1+B2)') swir2 = utils.band_math([swir2_fn], 'B1') ndvi = utils.band_math([nir_fn, red_fn], '(B1-B2)/(B1+B2)') blue_swir = utils.band_math([blue_fn, swir1_fn], 'B1/B2') # step 1 cloud_prob1 = (swir2 > 0.03) * (ndsi < 0.8) * (ndvi < 0.5) * (red > 0.15) mean_vis = (blue + green + red) / 3 cloud_prob2 = (np.abs(blue - mean_vis) / mean_vis + np.abs(green - mean_vis) / mean_vis + np.abs(red - mean_vis) / mean_vis) < 0.7 cloud_prob3 = (blue - 0.5 * red) > 0.08 cloud_prob4 = utils.band_math([nir_fn, swir1_fn], 'B1/B2>0.75') cloud = cloud_prob1 * cloud_prob2 * cloud_prob3 * cloud_prob4 cloud = cloud.astype(np.uint8) cnt_cloud = len(cloud[cloud == 1]) cloud_level = cnt_cloud / np.shape(cloud)[0] / np.shape(cloud)[1] print('cloud level:%.3f' % cloud_level) cloud_large = np.copy(cloud) * 0 # -- only the cloud over water was saved -- # labels_struct[0]: count; # labels_struct[1]: label matrix; # labels_struct[2]: [minY,minX,block_width,block_height,cnt] labels_struct = cv2.connectedComponentsWithStats(cloud, connectivity=4) img_h, img_w = cloud.shape for i in range(1, labels_struct[0]): patch = labels_struct[2][i] if patch[4] > 2000: cloud_large[labels_struct[1] == i] = 1 # cloud shadow detection PI = 3.1415 shadow_dire = sola + 180.0 if shadow_dire > 360.0: shadow_dire -= 360.0 cloud_height = [100 + 100 * i for i in range(100)] shadow_mean = [] for item in cloud_height: shadow_dist = item * np.tan(solz / 180.0 * PI) / 10.0 w_offset = np.sin(shadow_dire / 180.0 * PI) * shadow_dist h_offset = np.cos(shadow_dire / 180.0 * PI) * shadow_dist * -1 affine_m = np.array([[1, 0, w_offset], [0, 1, h_offset]]) cloud_shadow = cv2.warpAffine(cloud_large, affine_m, (img_w, img_h)) cloud_shadow = (cloud_shadow == 1) * (cloud_large != 1) shadow_mean.append(np.mean(green[cloud_shadow])) cloud_hight_opt = cloud_height[shadow_mean.index(min(shadow_mean))] shadow_dist_metric = cloud_hight_opt * np.tan(solz / 180.0 * PI) if cloud_hight_opt > 200 and cloud_hight_opt < 10000 and shadow_dist_metric < 5000: print('cloud height: %dm' % cloud_hight_opt) shadow_dist = cloud_hight_opt * np.tan( solz / 180.0 * PI) / pixel_size w_offset = np.sin(shadow_dire / 180.0 * PI) * shadow_dist h_offset = np.cos(shadow_dire / 180.0 * PI) * shadow_dist * -1 affine_m = np.array([[1, 0, w_offset], [0, 1, h_offset]]) cloud_shadow = cv2.warpAffine(cloud_large, affine_m, (img_w, img_h)) cloud_shadow = (cloud_shadow == 1) * (cloud_large != 1) cloud1 = np.copy(cloud) cloud1[cloud_shadow] = 2 cloud_all = np.copy(cloud) cloud_all[cloud_shadow] = 1 self.cloud = (cloud_all == 1) dst_fn = os.path.join(self.res_dir, self.pre_name + 'cloud.tif') utils.raster2tif(cloud1, self.geo_trans, self.proj_ref, dst_fn, type='uint8') kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2)) cloud_shadow = cv2.morphologyEx(cloud_shadow.astype(np.uint8), cv2.MORPH_OPEN, kernel) cloud_shadow_key = True else: cloud_shadow_key = False self.cloud = cloud == 1 cirrus = utils.band_math([cirrus_fn], 'B1') # step 1 cloud_prob1 = (red - 0.07) / (0.25 - 0.07) cloud_prob1[cloud_prob1 < 0] = 0 cloud_prob1[cloud_prob1 > 1] = 1 # step 2 cloud_prob2 = (ndsi + 0.1) / (0.2 + 0.1) cloud_prob2[cloud_prob2 < 0] = 0 cloud_prob2[cloud_prob2 > 1] = 1 cloud_prob = cloud_prob1 * cloud_prob2 # step 3: water cloud_prob[blue_swir > 2.5] = 0 cloud_prob = (cloud_prob * 100).astype(np.int) if cloud_shadow_key: self.water = (ndsi > -0.1) * (cloud_prob == 0) * ( cirrus < 0.012) * (cloud_shadow == 0) else: self.water = (ndsi > -0.1) * (cloud_prob == 0) * (cirrus < 0.012) # vector mask if vector is not None: self.vector_mask = utils.vector2mask(blue_fn, vector) self.water = self.water * (self.vector_mask == 0) else: self.vector_mask = self.water * 0
y_cord.pop() #cropping the image based on y_cord list crop_img = img[int(y_cord[1]) + 20:int(y_cord[0])] crop_blur = cv2.cvtColor(crop_img, cv2.COLOR_BGR2GRAY) #display_img("crop_blur", crop_blur) #Using standard threshold to create contrast between white/black keys _, th1 = cv2.threshold(crop_blur, 85, 150, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) display_img("threshold", th1) #################################### ####### using connected component detection algorithm to seperate all the black notes connectivity = 8 output = cv2.connectedComponentsWithStats(th1, connectivity, cv2.CV_32S) num_labels = output[0] labels = output[1] stats = output[2] centroids = output[3] print(centroids.shape) final_labels = [] #For loop only used for displaying for i in range(1, num_labels): if i == 0: text = "examining component {}/{} (background)".format( i + 1, num_labels) else: text = "examining component {}/{}".format(i + 1, num_labels)
# Threshold for an optimal value, it may vary depending on the image. har = img.copy() har[dst>0.01*dst.max()]=[0,0,255] cv2.imshow('har',har) # Corner with SubPixel Accuracy # Sometimes, you may need to find the corners with maximum accuracy. OpenCV comes with a function cv2.cornerSubPix() which further refines the corners detected with sub-pixel accuracy. Below is an example. As usual, we need to find the harris corners first. Then we pass the centroids of these corners (There may be a bunch of pixels at a corner, we take their centroid) to refine them. Harris corners are marked in red pixels and refined corners are marked in green pixels. For this function, we have to define the criteria when to stop the iteration. We stop it after a specified number of iteration or a certain accuracy is achieved, whichever occurs first. We also need to define the size of neighbourhood it would search for corners. 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.uint8(res) subpix = img.copy() subpix[res[:,1],res[:,0]]=[0,0,255] subpix[res[:,3],res[:,2]] = [0,255,0] cv2.imshow('sub pix',subpix)
import numpy as np orgImage = cv2.imread( 'C:/Users/JH/Desktop/playdata/Python_encore/Encore/temp/Image/KakaoTalk_20200623_131353244.jpg', cv2.IMREAD_GRAYSCALE) cv2.imshow('org', orgImage) resizeImage = cv2.resize(orgImage, (400, 400)) blurImage = cv2.GaussianBlur(resizeImage, (5, 5), 0) _, binaryImage = cv2.threshold(blurImage, 153, 255, cv2.THRESH_BINARY_INV) getROI = binaryImage[:300, :] contours, hierachy = cv2.findContours(getROI.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(getROI) leftList, topList, bottomList, RightList = [], [], [], [] for i in range(nlabels): if i == 0: continue leftList.append([i - 1, int(stats[i, cv2.CC_STAT_LEFT])]) topList.append([i - 1, int(stats[i, cv2.CC_STAT_TOP])]) bottomList.append( [i - 1, int(stats[i, cv2.CC_STAT_TOP] + stats[i, cv2.CC_STAT_HEIGHT])]) RightList.append( [i - 1, int(stats[i, cv2.CC_STAT_LEFT] + stats[i, cv2.CC_STAT_WIDTH])]) topIndex, leftIndex, bottomIndex = 0, 0, 0 mintopIndex = (min(i[1] for i in topList)) for i in topList:
def detect(viddir,frame_id, random_num): viddir = '/home/lby/lace-defect-detection-app/'+viddir print(viddir) print(frame_id) vidcap = cv2.VideoCapture(viddir) R = 5 vidcap.set(cv2.CAP_PROP_POS_FRAMES,frame_id) #找一个队列用来判别有没有缺陷 defect_center_queue=[] for i in range(4): defect_center_queue.append(np.array((0,0))) num = 0 while vidcap.isOpened(): cur_frame_num = vidcap.get(cv2.CAP_PROP_POS_FRAMES) ret,frame0 = vidcap.read() frame0_gray = cv2.cvtColor(frame0,cv2.COLOR_BGR2GRAY) frame0_gray = frame0_gray[490:1080,90:1440] if(not ret): break vidcap.set(cv2.CAP_PROP_POS_FRAMES,cur_frame_num+626)#or 626 ret,frame1 = vidcap.read() frame1_gray = cv2.cvtColor(frame1,cv2.COLOR_BGR2GRAY) frame1_gray = frame1_gray[490:1080,90:1440] vidcap.set(cv2.CAP_PROP_POS_FRAMES,cur_frame_num+1) Mu1,Sigma1 = AreaMuSigma(frame0_gray,R) Mu2,Sigma2 = AreaMuSigma(frame1_gray,R) KL_value = KL(Mu1,Sigma1,Mu2,Sigma2) KL_value = KL_value/np.max(KL_value) #后处理 kl_max = np.max(KL_value) _,mask = cv2.threshold(KL_value,0.1*kl_max,1,cv2.THRESH_BINARY) mask = mask.astype(np.uint8) #甚至可以膨胀一下 kernel = np.ones((10, 10), np.uint8) mask = cv2.dilate(mask, kernel) _,labels,status,centroids = cv2.connectedComponentsWithStats(mask)#labels,stats,centroids labels = labels.astype(np.uint8) status = np.delete(status,0,axis=0) max_idx=np.argmax(status[:,4],axis=0) + 1 #因为我把第一个删掉了 labels[labels != max_idx] = 0 labels[labels == max_idx] = 255 max_centroids = centroids[max_idx - 1] if judgeDefect(max_centroids,defect_center_queue): #暂时不知道为什么会框歪,所以加一个delta修正一下 delta = 30 max_status = status[max_idx - 1] left = int(max_status[0] - max_status[2]/2 + 90) top = int(max_status[1] -max_status[3]/2 + 490 + delta) right = int(max_status[0] + max_status[2]/2 + 90) bottom = int(max_status[1] + max_status[3]/2 + 490 + delta) cv2.rectangle(frame0, (left,top), (right,bottom),(0, 255, 0), 2) if(num==10): # prepare for the front page mask_save_path = '/home/lby/lace-defect-detection-app/src/static/result_mask_'+random_num+'.png' origin_save_path = '/home/lby/lace-defect-detection-app/src/static/result_origin_'+random_num+'.png' cv2.imwrite(mask_save_path, KL_value*255) cv2.imwrite(origin_save_path, frame0[490:1080,90:1440]) break #更新检测是否有缺陷列表 defect_center_queue.append(max_centroids) defect_center_queue.pop(0) num += 1
#cv2.waitKey(0) #cv2.imshow(imgName+"Global Thresholding (v = 127)", th1) cv2.imwrite(imgName+"_Global_Thresholding.png", th1) #cv2.waitKey(0) #cv2.imshow(imgName+"Adaptive Mean Thresholding", th2) cv2.imwrite(imgName+"_Adaptive_Mean_Thresholding.png", th2) #cv2.waitKey(0) #cv2.imshow(imgName+"Adaptive Gaussian Thresholding", th3) cv2.imwrite(imgName+"_Adaptive_Gaussian_Thresholding.png", th3) #cv2.waitKey(0) th1 = cv2.threshold(th1, 240, 255, 1)[1] # ensure binary th2 = cv2.threshold(th2, 240, 255, 1)[1] # ensure binary th3 = cv2.threshold(th3, 240, 255, 1)[1] # ensure binary labels = cv2.connectedComponentsWithStats(th1) labels2 = cv2.connectedComponentsWithStats(th2) labels3 = cv2.connectedComponentsWithStats(th3) print(labels3) def imshow_components(labels,num): # Map component labels to hue val #print(labels) label_hue = np.uint8(50000000*labels/np.max(labels)) #print(label_hue) blank_ch = 255*np.ones_like(label_hue) labeled_img = cv2.merge([label_hue, blank_ch, blank_ch]) # cvt to BGR for display labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)
def adjust0(fn_list): fn_base = fn_list[0] for i in range(len(fn_list) - 1): print('%d of %d...' % (i + 1, len(fn_list) - 1)) fn_move = fn_list[i + 1] ds = gdal.Open(fn_move) geo_trans = ds.GetGeoTransform() proj_ref = ds.GetProjection() data_base = cv2.imread(fn_base).astype(float) data_move = cv2.imread(fn_move).astype(float) # 色调匹配 # diff = np.sum(np.abs(data_move - data_base) / data_base, axis=2) # valid_key = diff < 0.5 # for n_band in range(3): # band_base = data_base[:, :, n_band] # band_move = data_move[:, :, n_band] # valid_key_t = valid_key * (band_base>10) * (band_base<240) * (band_move>10) * (band_move<240) # invalid_key = (band_base==0) * (band_move==0) # band_base = band_base[valid_key_t] # band_move = band_move[valid_key_t] # slope, intercept, r_value, p_value, std_err = st.linregress(band_move, band_base) # data_move_single = data_move[:, :, n_band] * slope + intercept # data_move_single[invalid_key] = 0 # data_move[:, :, n_band] = data_move_single # 确定替换条件 data_move_gray = color.rgb2gray(data_move.astype(np.uint8)) * 255 data_base_gray = color.rgb2gray(data_base.astype(np.uint8)) * 255 thresh = 150 key = (data_move_gray <= thresh) * (data_base_gray > thresh) # 去除碎斑 label_cnt = np.shape(key)[0] * np.shape(key)[1] labels_struct = cv2.connectedComponentsWithStats(key.astype(np.uint8), connectivity=4) key_simp = np.zeros(key.shape, np.uint8) area_thresh = 200 base_std = np.std(data_base, axis=2) for j in range(labels_struct[0]): area_tmp = labels_struct[2][j][4] if (area_tmp > area_thresh) and (area_tmp < label_cnt * 0.1): key_tmp = labels_struct[1] == j # 云块一般为灰白色,std较低 base_gray_extract = base_std[key_tmp] base_patch_std = np.mean(base_gray_extract) if base_patch_std < 10: key_simp[key_tmp] = 1 key = key_simp # 云区域膨胀 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (8, 8)) key = cv2.dilate(key.astype(np.uint8), kernel) # 膨胀 key = key == 1 # dilated2用于确定融合范围 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10)) dilated2 = cv2.dilate(key.astype(np.uint8), kernel) * 255 # 目标替换 for j in range(3): band_data = data_base[:, :, j] data_select = data_move[:, :, j] band_data[key] = data_select[key] data_base[:, :, j] = band_data # 泊松融合 mask = key.astype(np.uint8) * 255 labels_struct = cv2.connectedComponentsWithStats(mask, connectivity=8) label_cnt = np.shape(mask)[0] * np.shape(mask)[1] bg_img = data_base.astype(np.uint8) data_move = data_move.astype(np.uint8) for i in range(labels_struct[0]): area_tmp = labels_struct[2][i][4] if (area_tmp > 100) and (area_tmp < label_cnt * 0.1): block_w0 = int(labels_struct[2][i][0]) block_w1 = int(labels_struct[2][i][0] + labels_struct[2][i][2]) block_h0 = int(labels_struct[2][i][1]) block_h1 = int(labels_struct[2][i][1] + labels_struct[2][i][3]) fg_img = data_move[block_h0:block_h1, block_w0:block_w1, :] mask_sub = dilated2[block_h0:block_h1, block_w0:block_w1] center = (int( (block_w0 + block_w1) / 2), int((block_h0 + block_h1) / 2)) output = cv2.seamlessClone(fg_img, bg_img, mask_sub, center, cv2.NORMAL_CLONE) bg_img = output dst_fn = fn_base.replace('.tif', '_mosaic.tif') output_flip = np.copy(output) output_flip[:, :, 0] = output[:, :, 2] output_flip[:, :, 2] = output[:, :, 0] utils.raster2tif(output_flip.astype(np.uint8), geo_trans, proj_ref, dst_fn, type='uint8', mask=True) fn_base = dst_fn
def adjust(fn_list, fn_base_clear): img_base_clear = cv2.imread(fn_base_clear) ds = gdal.Open(fn_list[0]) geo_trans = ds.GetGeoTransform() proj_ref = ds.GetProjection() img_width = ds.RasterXSize img_height = ds.RasterYSize img_stack = np.zeros((img_height, img_width, len(fn_list)), np.uint8) for i, item in enumerate(fn_list): img = cv2.imread(item) img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img_stack[:, :, i] = img_gray min_stack = np.min(img_stack, axis=2) max_stack = np.max(img_stack, axis=2) median_stack = np.median(img_stack, axis=2) imedian_stack = np.zeros((img_height, img_width), np.uint8) # 判断基准图像的云分布 print('基准影像云检测...') img = cv2.imread(fn_list[0]) img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img_std = np.std(img.astype(float), axis=2) key_cloud = (img_gray == max_stack) * (img_gray > 150) * (img_std < 10) + ( img_gray == 255) # cloud cloud0 = np.zeros(key_cloud.shape, np.uint8) cloud0[key_cloud] = 255 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) cloud0 = cv2.morphologyEx(cloud0, cv2.MORPH_OPEN, kernel) # 开操作去除碎斑 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) for i in range(20): cloud0 = cv2.dilate(cloud0, kernel) # dst_fn = fn_list[0].replace('.tif', '_cloud_shadow.tif') # utils.raster2tif(cloud0.astype(np.uint8), geo_trans, proj_ref, dst_fn, type='uint8', mask=True) # 判断其他影像的云分布 print('其它影像云检测...') cloud_stack = np.zeros( (np.shape(cloud0)[0], np.shape(cloud0)[1], len(fn_list) - 1), np.uint8) rgb_stack = [] for i, item in enumerate(fn_list[1:]): print(' %s...' % item) img = cv2.imread(item) rgb_stack.append(img) img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img_std = np.std(img.astype(float), axis=2) key_cloud = (img_gray == max_stack) * (img_gray > 150) * ( img_std < 10) + (img_gray == 255) # cloud dst_fn = fn_list[0].replace('.tif', '_cloud_shadow.tif') cloud = np.zeros(key_cloud.shape, np.uint8) cloud[key_cloud] = 255 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) cloud = cv2.morphologyEx(cloud, cv2.MORPH_OPEN, kernel) # 开操作去除碎斑 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) for n in range(10): cloud = cv2.dilate(cloud, kernel) cloud_stack[:, :, i] = (cloud == 255).astype(np.uint8) # 遍历寻找最合适的影像进行替换 print('泊松融合...') labels_struct = cv2.connectedComponentsWithStats(cloud0, connectivity=8) label_cnt = np.shape(cloud0)[0] * np.shape(cloud0)[1] img_bg = cv2.imread(fn_list[0]) kernel_dilate = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2)) for i in range(labels_struct[0]): area_tmp = labels_struct[2][i][4] cloud_cnt = np.Inf if (area_tmp < label_cnt * 0.5): key = labels_struct[1] == i key_uint8 = key.astype(np.uint8) * 255 # key_dilation = cv2.dilate(key_uint8, kernel_dilate) # key_edge = (key_uint8==0) * (key_dilation==255) for j in range(len(fn_list) - 1): cloud_tmp = cloud_stack[:, :, j] cloud_cnt_tmp = np.sum(cloud_tmp[key]) if cloud_cnt_tmp == 0: cloud_cnt = cloud_cnt_tmp select_index = j break elif cloud_cnt_tmp < cloud_cnt: cloud_cnt = cloud_cnt_tmp select_index = j if cloud_cnt != 0: img_fg = img_base_clear else: img_fg = rgb_stack[select_index] block_w0 = int(labels_struct[2][i][0]) block_w1 = int(labels_struct[2][i][0] + labels_struct[2][i][2]) block_h0 = int(labels_struct[2][i][1]) block_h1 = int(labels_struct[2][i][1] + labels_struct[2][i][3]) img_fg_sub = img_fg[block_h0:block_h1, block_w0:block_w1, :] mask_sub = cloud0[block_h0:block_h1, block_w0:block_w1] center = (int( (block_w0 + block_w1) / 2), int((block_h0 + block_h1) / 2)) output = cv2.seamlessClone(img_fg_sub, img_bg, mask_sub, center, cv2.NORMAL_CLONE) img_bg = output output = np.flip(output, axis=2) dst_fn = fn_list[0].replace('.tif', '_mosaic.tif') utils.raster2tif(output, geo_trans, proj_ref, dst_fn, type='uint8', mask=True)
all_out = merge(out, num, padding) number = int(round(all_out.sum())) print('start drawing circles') points = all_out * 100 res, binary = cv2.threshold(points, 3.5, 255, cv2.THRESH_BINARY) if number < 300: out = cv2.dilate(binary, None, iterations=2) else: out = cv2.dilate(binary, None, iterations=1) out = np.array(out, dtype='uint8') nLabels, labels, stats, centroids = cv2.connectedComponentsWithStats( out, connectivity=4) centroids = centroids[1:, ] nLabels = nLabels - 1 center_x = centroids[:, 0] center_y = centroids[:, 1] all_img = cv2.imread(outfile, 1) for i in range(nLabels): cv2.circle(all_img, (int(round(center_x[i])), int(round(center_y[i]))), 5, (0, 0, 255), -1) cv2.putText(all_img, 'Number: ' + str(nLabels), (int(allRadius[0] - 300), int(allRadius[0])),
kernel = np.ones((5, 5), np.uint8) cv2.imshow('gray2', gray) gray = cv2.erode(gray, kernel, 2) # 通过腐蚀运算填补黑块内部的白色空隙 cv2.imshow('gray1', gray) gray = cv2.threshold(gray, 90, 255, cv2.THRESH_BINARY)[1] # 设置过滤无关边界内容 gray = cv2.GaussianBlur(gray, (3, 3), 0) # 使图像模糊,便于减少无关图像干扰 gray = np.float32(gray) dst = cv2.cornerHarris(gray, 2, 3, 0.04) # 找到Harris角点 dst = cv2.dilate(dst, None) # 膨胀操作 ret, dst = cv2.threshold(dst, 0.01 * dst.max(), 255, 0) # 二值化,除去不相关图像 dst = cv2.GaussianBlur(dst, (3, 3), 0) # 使图像模糊,便于减少无关图像干扰 dst = np.uint8(dst) centroids = cv2.connectedComponentsWithStats(dst)[3] # 寻找连通区域 criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001 ) # 设置终止条件,迭代30次或移动0.001 corners = cv2.cornerSubPix(gray, np.float32(centroids), (5, 5), (-1, -1), criteria) # cv2.cornerSubPix()检测十分精细,但不便于显示 res = np.hstack((centroids, corners)) res = np.int0(res) # cv2.cornerHarris检测出的角点,粗略 pointImg[dst > 0.1012 * dst.max()] = [0, 0, 255] # cv2.cornerSubPix检测出的角点,精确 pointImg[res[:, 1], res[:, 0]] = [0, 0, 255] # 绿色点为修正点 pointImg[res[:, 3], res[:, 2]] = [0, 255, 0] cv2.imshow('dst2', pointImg)
img_std = np.std(img.astype(float), axis=2) key_cloud = (img_gray == max_stack) * (img_gray > 150) * (img_std < 10) + ( img_gray == 255) # cloud dst_fn = fn_list[0].replace('.tif', '_cloud_shadow.tif') cloud = np.zeros(key_cloud.shape, np.uint8) cloud[key_cloud] = 255 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) cloud = cv2.morphologyEx(cloud, cv2.MORPH_OPEN, kernel) # 开操作去除碎斑 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) for n in range(10): cloud = cv2.dilate(cloud, kernel) cloud_stack[:, :, i] = (cloud == 255).astype(np.uint8) # 遍历寻找最合适的影像进行替换 print('泊松融合...') labels_struct = cv2.connectedComponentsWithStats(cloud0, connectivity=8) label_cnt = np.shape(cloud0)[0] * np.shape(cloud0)[1] img_bg = cv2.imread(fn_list[0]) kernel_dilate = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2)) for i in range(labels_struct[0]): area_tmp = labels_struct[2][i][4] cloud_cnt = np.Inf if (area_tmp < label_cnt * 0.5): key = labels_struct[1] == i key_uint8 = key.astype(np.uint8) * 255 # key_dilation = cv2.dilate(key_uint8, kernel_dilate) # key_edge = (key_uint8==0) * (key_dilation==255) for j in range(len(fn_list) - 1): cloud_tmp = cloud_stack[:, :, j] cloud_cnt_tmp = np.sum(cloud_tmp[key]) if cloud_cnt_tmp == 0: