def sample_hard_negatives(img, roi_mask, out_dir, img_id, abn, patch_size=256, neg_cutoff=.35, nb_bkg=100, start_sample_nb=0, bkg_dir='background', verbose=False): '''WARNING: the definition of hns may be problematic. There has been study showing that the context of an ROI is also useful for classification. ''' bkg_out = os.path.join(out_dir, bkg_dir) basename = '_'.join([img_id, str(abn)]) img = add_img_margins(img, patch_size/2) roi_mask = add_img_margins(roi_mask, patch_size/2) # Get ROI bounding box. roi_mask_8u = roi_mask.astype('uint8') ver = (cv2.__version__).split('.') if int(ver[0]) < 3: contours,_ = cv2.findContours( roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) else: _,contours,_ = cv2.findContours( roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cont_areas = [ cv2.contourArea(cont) for cont in contours ] idx = np.argmax(cont_areas) # find the largest contour. rx,ry,rw,rh = cv2.boundingRect(contours[idx]) if verbose: M = cv2.moments(contours[idx]) cx = int(M['m10']/M['m00']) cy = int(M['m01']/M['m00']) print "ROI centroid=", (cx,cy); sys.stdout.flush() rng = np.random.RandomState(12345) # Sample hard negative samples. sampled_bkg = start_sample_nb while sampled_bkg < start_sample_nb + nb_bkg: x1,x2 = (rx - patch_size/2, rx + rw + patch_size/2) y1,y2 = (ry - patch_size/2, ry + rh + patch_size/2) x1 = crop_val(x1, patch_size/2, img.shape[1] - patch_size/2) x2 = crop_val(x2, patch_size/2, img.shape[1] - patch_size/2) y1 = crop_val(y1, patch_size/2, img.shape[0] - patch_size/2) y2 = crop_val(y2, patch_size/2, img.shape[0] - patch_size/2) x = rng.randint(x1, x2) y = rng.randint(y1, y2) if not overlap_patch_roi((x,y), patch_size, roi_mask, cutoff=neg_cutoff): patch = img[y - patch_size/2:y + patch_size/2, x - patch_size/2:x + patch_size/2] patch_img = toimage( patch.astype('int32'), high=patch.max(), low=patch.min(), mode='I') filename = basename + "_%04d" % (sampled_bkg) + ".png" fullname = os.path.join(bkg_out, filename) patch_img.save(fullname) sampled_bkg += 1 if verbose: print "sampled a hns patch at (x,y) center=", (x,y) sys.stdout.flush()
def sample_hard_negatives(image, roi_mask, out_dir, image_id, abn_id, patch_size=256, neg_cutoff=.35, nb_bkg=100, start_sample_nb=0, bkg_dir="background", verbose=False): """WARNING: the definition of hns may be problematic. There has been study showing that the context of an ROI is also useful for classification. """ bkg_out = os.path.join(out_dir, bkg_dir) if not os.path.exists(bkg_out): os.makedirs(bkg_out) basename = "_".join([image_id, str(abn_id)]) image = add_img_margins(image, patch_size/2) roi_mask = add_img_margins(roi_mask, patch_size/2) # Get ROI bounding box. roi_mask_8u = roi_mask.astype("uint8") ver = (cv2.__version__).split(".") contours, _ = cv2.findContours(roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cont_areas = [cv2.contourArea(cont) for cont in contours] idx = np.argmax(cont_areas) # find the largest contour. rx, ry, rw, rh = cv2.boundingRect(contours[idx]) if verbose: M = cv2.moments(contours[idx]) cx = int(M["m10"]/M["m00"]) cy = int(M["m01"]/M["m00"]) print "ROI centroid=", (cx, cy) sys.stdout.flush() rng = np.random.RandomState(12345) # Sample hard negative samples. sampled_bkg = start_sample_nb while sampled_bkg < start_sample_nb + nb_bkg: x1, x2 = (rx - patch_size/2, rx + rw + patch_size/2) y1, y2 = (ry - patch_size/2, ry + rh + patch_size/2) x1 = crop_val(x1, patch_size/2, image.shape[1] - patch_size/2) x2 = crop_val(x2, patch_size/2, image.shape[1] - patch_size/2) y1 = crop_val(y1, patch_size/2, image.shape[0] - patch_size/2) y2 = crop_val(y2, patch_size/2, image.shape[0] - patch_size/2) x = rng.randint(x1, x2) y = rng.randint(y1, y2) if not overlap_patch_roi((x, y), patch_size, roi_mask, cutoff=neg_cutoff): patch = image[y - patch_size/2:y + patch_size/2, x - patch_size/2:x + patch_size/2] patch = patch.astype("int32") patch_image = toimage(patch, high=patch.max(), low=patch.min(), mode="I") filename = basename + "_%04d" % (sampled_bkg) + ".png" fullname = os.path.join(bkg_out, filename) patch_image.save(fullname) sampled_bkg += 1 if verbose: print "sampled a hns patch at (x,y) center=", (x, y) sys.stdout.flush()
def sample_blob_negatives(img, roi_mask, out_dir, img_id, abn, blob_detector, patch_size=256, neg_cutoff=.35, nb_bkg=100, start_sample_nb=0, bkg_dir='background', verbose=False): bkg_out = os.path.join(out_dir, bkg_dir) basename = '_'.join([img_id, str(abn)]) img = add_img_margins(img, patch_size/2) roi_mask = add_img_margins(roi_mask, patch_size/2) # Get ROI bounding box.获取ROI边界 roi_mask_8u = roi_mask.astype('uint8') ver = (cv2.__version__).split('.') if int(ver[0]) < 3: contours,_ = cv2.findContours( roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) else: _,contours,_ = cv2.findContours( roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cont_areas = [ cv2.contourArea(cont) for cont in contours ] idx = np.argmax(cont_areas) # find the largest contour. rx,ry,rw,rh = cv2.boundingRect(contours[idx]) if verbose: M = cv2.moments(contours[idx]) cx = int(M['m10']/M['m00']) cy = int(M['m01']/M['m00']) print ("ROI centroid=", (cx,cy)); sys.stdout.flush() # Sample blob negative samples.阴性斑点样本采样 # 采取特征点? key_pts = blob_detector.detect((img/img.max()*255).astype('uint8')) rng = np.random.RandomState(12345) key_pts = rng.permutation(key_pts) sampled_bkg = 0 for kp in key_pts: if sampled_bkg >= nb_bkg: break x,y = int(kp.pt[0]), int(kp.pt[1]) if not overlap_patch_roi((x,y), patch_size, roi_mask, cutoff=neg_cutoff): patch = img[y - patch_size/2:y + patch_size/2, x - patch_size/2:x + patch_size/2] patch_img = toimage( patch.astype('int32'), high=patch.max(), low=patch.min(), mode='I') filename = basename + "_%04d" % (start_sample_nb + sampled_bkg) + ".png" fullname = os.path.join(bkg_out, filename) patch_img.save(fullname) if verbose: print ("sampled a blob patch at (x,y) center=", (x,y)) sys.stdout.flush() sampled_bkg += 1 return sampled_bkg
def sample_blob_negatives(img, roi_mask, out_dir, img_id, abn, blob_detector, patch_size=256, neg_cutoff=.35, nb_bkg=100, start_sample_nb=0, bkg_dir='background', verbose=False): bkg_out = os.path.join(out_dir, bkg_dir) basename = '_'.join([img_id, str(abn)]) img = add_img_margins(img, patch_size/2) roi_mask = add_img_margins(roi_mask, patch_size/2) # Get ROI bounding box. roi_mask_8u = roi_mask.astype('uint8') ver = (cv2.__version__).split('.') if int(ver[0]) < 3: contours,_ = cv2.findContours( roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) else: _,contours,_ = cv2.findContours( roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cont_areas = [ cv2.contourArea(cont) for cont in contours ] idx = np.argmax(cont_areas) # find the largest contour. rx,ry,rw,rh = cv2.boundingRect(contours[idx]) if verbose: M = cv2.moments(contours[idx]) cx = int(M['m10']/M['m00']) cy = int(M['m01']/M['m00']) print "ROI centroid=", (cx,cy); sys.stdout.flush() # Sample blob negative samples. key_pts = blob_detector.detect((img/img.max()*255).astype('uint8')) rng = np.random.RandomState(12345) key_pts = rng.permutation(key_pts) sampled_bkg = 0 for kp in key_pts: if sampled_bkg >= nb_bkg: break x,y = int(kp.pt[0]), int(kp.pt[1]) if not overlap_patch_roi((x,y), patch_size, roi_mask, cutoff=neg_cutoff): patch = img[y - patch_size/2:y + patch_size/2, x - patch_size/2:x + patch_size/2] patch_img = toimage( patch.astype('int32'), high=patch.max(), low=patch.min(), mode='I') filename = basename + "_%04d" % (start_sample_nb + sampled_bkg) + ".png" fullname = os.path.join(bkg_out, filename) patch_img.save(fullname) if verbose: print "sampled a blob patch at (x,y) center=", (x,y) sys.stdout.flush() sampled_bkg += 1 return sampled_bkg
def sample_blob_negatives(image, roi_mask, out_dir, image_id, abn_id, blob_detector, patch_size=256, neg_cutoff=.35, nb_bkg=100, start_sample_nb=0, bkg_dir="background", verbose=False): bkg_out = os.path.join(out_dir, bkg_dir) if not os.path.exists(bkg_out): os.makedirs(bkg_out) basename = "_".join([image_id, str(abn_id)]) image = add_img_margins(image, patch_size/2) roi_mask = add_img_margins(roi_mask, patch_size/2) # Get ROI bounding box. roi_mask_8u = roi_mask.astype("uint8") ver = (cv2.__version__).split(".") contours, _ = cv2.findContours(roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cont_areas = [cv2.contourArea(cont) for cont in contours] idx = np.argmax(cont_areas) # find the largest contour. rx, ry, rw, rh = cv2.boundingRect(contours[idx]) if verbose: M = cv2.moments(contours[idx]) cx = int(M["m10"]/M["m00"]) cy = int(M["m01"]/M["m00"]) print "ROI centroid=", (cx, cy) sys.stdout.flush() # Sample blob negative samples. key_pts = blob_detector.detect((image/image.max()*255).astype("uint8")) rng = np.random.RandomState(12345) key_pts = rng.permutation(key_pts) sampled_bkg = 0 for kp in key_pts: if sampled_bkg >= nb_bkg: break x, y = int(kp.pt[0]), int(kp.pt[1]) if not overlap_patch_roi((x, y), patch_size, roi_mask, cutoff=neg_cutoff): patch = image[y - patch_size/2:y + patch_size/2, x - patch_size/2:x + patch_size/2] patch = patch.astype("int32") patch_image = toimage(patch, high=patch.max(), low=patch.min(), mode="I") filename = basename + "_%04d" % (start_sample_nb + sampled_bkg) + ".png" fullname = os.path.join(bkg_out, filename) patch_image.save(fullname) if verbose: print "sampled a blob patch at (x,y) center=", (x, y) sys.stdout.flush() sampled_bkg += 1 return sampled_bkg
def sample_patches(img, roi_mask, out_dir, img_id, abn, pos, patch_size=256, pos_cutoff=.75, neg_cutoff=.35, nb_bkg=100, nb_abn=100, start_sample_nb=0, bkg_dir='background', pos_dir='malignant', neg_dir='benign', verbose=False): if pos: roi_out = os.path.join(out_dir, pos_dir) else: roi_out = os.path.join(out_dir, neg_dir) bkg_out = os.path.join(out_dir, bkg_dir) basename = '_'.join([img_id, str(abn)]) img = add_img_margins(img, patch_size/2) roi_mask = add_img_margins(roi_mask, patch_size/2) # Get ROI bounding box. roi_mask_8u = roi_mask.astype('uint8') ver = (cv2.__version__).split('.') if int(ver[0]) < 3: contours,_ = cv2.findContours( roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) else: _,contours,_ = cv2.findContours( roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cont_areas = [ cv2.contourArea(cont) for cont in contours ] idx = np.argmax(cont_areas) # find the largest contour. rx,ry,rw,rh = cv2.boundingRect(contours[idx]) if verbose: M = cv2.moments(contours[idx]) cx = int(M['m10']/M['m00']) cy = int(M['m01']/M['m00']) print "ROI centroid=", (cx,cy); sys.stdout.flush() rng = np.random.RandomState(12345) # Sample abnormality first. sampled_abn = 0 nb_try = 0 while sampled_abn < nb_abn: x = rng.randint(rx, rx + rw) y = rng.randint(ry, ry + rh) nb_try += 1 if nb_try >= 1000: print "Nb of trials reached maximum, decrease overlap cutoff by 0.05" sys.stdout.flush() pos_cutoff -= .05 nb_try = 0 if pos_cutoff <= .0: raise Exception("overlap cutoff becomes non-positive, " "check roi mask input.") # import pdb; pdb.set_trace() if overlap_patch_roi((x,y), patch_size, roi_mask, cutoff=pos_cutoff): patch = img[y - patch_size/2:y + patch_size/2, x - patch_size/2:x + patch_size/2] patch_img = toimage( patch.astype('int32'), high=patch.max(), low=patch.min(), mode='I') # patch = patch.reshape((patch.shape[0], patch.shape[1], 1)) filename = basename + "_%04d" % (sampled_abn) + ".png" fullname = os.path.join(roi_out, filename) # import pdb; pdb.set_trace() patch_img.save(fullname) sampled_abn += 1 nb_try = 0 if verbose: print "sampled an abn patch at (x,y) center=", (x,y) sys.stdout.flush() # Sample background. sampled_bkg = start_sample_nb while sampled_bkg < start_sample_nb + nb_bkg: x = rng.randint(patch_size/2, img.shape[1] - patch_size/2) y = rng.randint(patch_size/2, img.shape[0] - patch_size/2) if not overlap_patch_roi((x,y), patch_size, roi_mask, cutoff=neg_cutoff): patch = img[y - patch_size/2:y + patch_size/2, x - patch_size/2:x + patch_size/2] patch_img = toimage( patch.astype('int32'), high=patch.max(), low=patch.min(), mode='I') filename = basename + "_%04d" % (sampled_bkg) + ".png" fullname = os.path.join(bkg_out, filename) patch_img.save(fullname) sampled_bkg += 1 if verbose: print "sampled a bkg patch at (x,y) center=", (x,y) sys.stdout.flush()
def sample_patches(img, roi_mask, out_dir, img_id, abn, pos, patch_size=256, pos_cutoff=.75, neg_cutoff=.35, nb_bkg=100, nb_abn=100, start_sample_nb=0, bkg_dir='background', pos_dir='malignant', neg_dir='benign', verbose=False): if pos: #阳性, roi_out = os.path.join(out_dir, pos_dir) else: #阴性 roi_out = os.path.join(out_dir, neg_dir) bkg_out = os.path.join(out_dir, bkg_dir) basename = '_'.join([img_id, str(abn)]) img = add_img_margins(img, patch_size/2) roi_mask = add_img_margins(roi_mask, patch_size/2) # Get ROI bounding box. #获取边界框 roi_mask_8u = roi_mask.astype('uint8') ver = (cv2.__version__).split('.') if int(ver[0]) < 3: #寻找图像中物体的轮廓(病变区域,不规则轮廓)返回向量集 contours,_ = cv2.findContours( roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) else: _,contours,_ = cv2.findContours( roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #计算轮廓面积 cont_areas = [ cv2.contourArea(cont) for cont in contours ] idx = np.argmax(cont_areas) # find the largest contour.找到面积最大的轮廓索引值 #边界左上角坐标及宽高 #boundingRect,用一个最小的矩形,把找到的形状包起来 rx,ry,rw,rh = cv2.boundingRect(contours[idx]) if verbose: # 将计算得到的矩以一个字典的形式返回至M M = cv2.moments(contours[idx]) cx = int(M['m10']/M['m00']) cy = int(M['m01']/M['m00']) print ("ROI centroid=", (cx,cy)); sys.stdout.flush() rng = np.random.RandomState(12345) # Sample abnormality first.采样异常图片先进行 sampled_abn = 0 nb_try = 0 while sampled_abn < nb_abn: x = rng.randint(rx, rx + rw) y = rng.randint(ry, ry + rh) nb_try += 1 if nb_try >= 1000: # 试验的Nb达到最大值,重叠截止以0.05幅度降低 print ("Nb of trials reached maximum, decrease overlap cutoff by 0.05") sys.stdout.flush() pos_cutoff -= .05 nb_try = 0 if pos_cutoff <= .0: # 重叠截止值达到了非阳性界限,检查感性区域掩码输入值 raise Exception("overlap cutoff becomes non-positive, " "check roi mask input.") # import pdb; pdb.set_trace() if overlap_patch_roi((x,y), patch_size, roi_mask, cutoff=pos_cutoff): patch = img[y - patch_size/2:y + patch_size/2, x - patch_size/2:x + patch_size/2] patch_img = toimage( patch.astype('int32'), high=patch.max(), low=patch.min(), mode='I') # patch = patch.reshape((patch.shape[0], patch.shape[1], 1)) filename = basename + "_%04d" % (sampled_abn) + ".png" fullname = os.path.join(roi_out, filename) # import pdb; pdb.set_trace() patch_img.save(fullname) sampled_abn += 1 #异常样本数量记录 nb_try = 0 if verbose: # 将异常样本的块坐标显示 print ("sampled an abn patch at (x,y) center=", (x,y)) sys.stdout.flush() # Sample background. sampled_bkg = start_sample_nb while sampled_bkg < start_sample_nb + nb_bkg: x = rng.randint(patch_size/2, img.shape[1] - patch_size/2) y = rng.randint(patch_size/2, img.shape[0] - patch_size/2) if not overlap_patch_roi((x,y), patch_size, roi_mask, cutoff=neg_cutoff): patch = img[y - patch_size/2:y + patch_size/2, x - patch_size/2:x + patch_size/2] patch_img = toimage( patch.astype('int32'), high=patch.max(), low=patch.min(), mode='I') filename = basename + "_%04d" % (sampled_bkg) + ".png" fullname = os.path.join(bkg_out, filename) patch_img.save(fullname) sampled_bkg += 1 if verbose: # 将样本背景中心块坐标显示 print ("sampled a bkg patch at (x,y) center=", (x,y)) sys.stdout.flush()
def sample_hard_negatives(img, roi_mask, out_dir, img_id, abn, patch_size=256, neg_cutoff=.35, nb_bkg=100, start_sample_nb=0, bkg_dir='background', verbose=False): '''WARNING: the definition of hns may be problematic. There has been study showing that the context of an ROI is also useful for classification. ''' # 添加背景目录并命名 bkg_out = os.path.join(out_dir, bkg_dir) basename = '_'.join([img_id, str(abn)]) # 图像加0边距,掩膜同样处理 img = add_img_margins(img, patch_size/2) roi_mask = add_img_margins(roi_mask, patch_size/2) # Get ROI bounding box. roi_mask_8u = roi_mask.astype('uint8') ver = (cv2.__version__).split('.') if int(ver[0]) < 3: contours,_ = cv2.findContours( roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) else: _,contours,_ = cv2.findContours( roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cont_areas = [ cv2.contourArea(cont) for cont in contours ] idx = np.argmax(cont_areas) # find the largest contour. rx,ry,rw,rh = cv2.boundingRect(contours[idx]) if verbose: M = cv2.moments(contours[idx]) cx = int(M['m10']/M['m00']) cy = int(M['m01']/M['m00']) print ("ROI centroid=", (cx,cy)); sys.stdout.flush() rng = np.random.RandomState(12345) # Sample hard negative samples.难类样本采样 sampled_bkg = start_sample_nb while sampled_bkg < start_sample_nb + nb_bkg: # 扩大感兴趣区域,取不小于patch_size/2,不超过img.shape - patch_size/2的x,y的随机值 x1,x2 = (rx - patch_size/2, rx + rw + patch_size/2) y1,y2 = (ry - patch_size/2, ry + rh + patch_size/2) x1 = crop_val(x1, patch_size/2, img.shape[1] - patch_size/2) x2 = crop_val(x2, patch_size/2, img.shape[1] - patch_size/2) y1 = crop_val(y1, patch_size/2, img.shape[0] - patch_size/2) y2 = crop_val(y2, patch_size/2, img.shape[0] - patch_size/2) x = rng.randint(x1, x2) y = rng.randint(y1, y2) # 如果patch与掩码不重叠则执行 if not overlap_patch_roi((x,y), patch_size, roi_mask, cutoff=neg_cutoff): # 选取图像中patch patch = img[y - patch_size/2:y + patch_size/2, x - patch_size/2:x + patch_size/2] # patch由数组转为图像,并保存至背景 patch_img = toimage( patch.astype('int32'), high=patch.max(), low=patch.min(), mode='I') filename = basename + "_%04d" % (sampled_bkg) + ".png" fullname = os.path.join(bkg_out, filename) patch_img.save(fullname) sampled_bkg += 1 if verbose: print ("sampled a hns patch at (x,y) center=", (x,y)) sys.stdout.flush()
def sample_patches(img, roi_mask, out_dir, img_id, abn, pos, patch_size=256, pos_cutoff=.75, neg_cutoff=.35, nb_bkg=100, nb_abn=100, start_sample_nb=0, itype='calc', bkg_dir='background', calc_pos_dir='calc_mal', calc_neg_dir='calc_ben', mass_pos_dir='mass_mal', mass_neg_dir='mass_ben', verbose=False): if pos: if itype == 'calc': roi_out = os.path.join(out_dir, calc_pos_dir) else: roi_out = os.path.join(out_dir, mass_pos_dir) else: if itype == 'calc': roi_out = os.path.join(out_dir, calc_neg_dir) else: roi_out = os.path.join(out_dir, mass_neg_dir) bkg_out = os.path.join(out_dir, bkg_dir) basename = '_'.join([img_id, str(abn)]) img = add_img_margins(img, patch_size / 2) roi_mask = add_img_margins(roi_mask, patch_size / 2) # Get ROI bounding box. roi_mask_8u = roi_mask.astype('uint8') ver = (cv2.__version__).split('.') if int(ver[0]) < 3: contours, _ = cv2.findContours(roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) else: _, contours, _ = cv2.findContours(roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cont_areas = [cv2.contourArea(cont) for cont in contours] idx = np.argmax(cont_areas) # find the largest contour. rx, ry, rw, rh = cv2.boundingRect(contours[idx]) if verbose: M = cv2.moments(contours[idx]) try: cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) print "ROI centroid=", (cx, cy) sys.stdout.flush() except ZeroDivisionError: print "ROI centroid=Unknown" sys.stdout.flush() rng = np.random.RandomState(12345) # Sample abnormality first. sampled_abn = 0 nb_try = 0 while sampled_abn < nb_abn: x = rng.randint(rx, rx + rw) y = rng.randint(ry, ry + rh) nb_try += 1 if nb_try >= 1000: print "Nb of trials reached maximum, decrease overlap cutoff by 0.05" sys.stdout.flush() pos_cutoff -= .05 nb_try = 0 if pos_cutoff <= .0: raise Exception("overlap cutoff becomes non-positive, " "check roi mask input.") # import pdb; pdb.set_trace() if overlap_patch_roi((x, y), patch_size, roi_mask, cutoff=pos_cutoff): patch = img[y - patch_size / 2:y + patch_size / 2, x - patch_size / 2:x + patch_size / 2] patch = patch.astype('int32') patch_img = toimage(patch, high=patch.max(), low=patch.min(), mode='I') # patch = patch.reshape((patch.shape[0], patch.shape[1], 1)) filename = basename + "_%04d" % (sampled_abn) + ".png" fullname = os.path.join(roi_out, filename) # import pdb; pdb.set_trace() patch_img.save(fullname) sampled_abn += 1 nb_try = 0 if verbose: print "sampled an abn patch at (x,y) center=", (x, y) sys.stdout.flush() # Sample background. sampled_bkg = start_sample_nb while sampled_bkg < start_sample_nb + nb_bkg: x = rng.randint(patch_size / 2, img.shape[1] - patch_size / 2) y = rng.randint(patch_size / 2, img.shape[0] - patch_size / 2) if not overlap_patch_roi( (x, y), patch_size, roi_mask, cutoff=neg_cutoff): patch = img[y - patch_size / 2:y + patch_size / 2, x - patch_size / 2:x + patch_size / 2] patch = patch.astype('int32') patch_img = toimage(patch, high=patch.max(), low=patch.min(), mode='I') filename = basename + "_%04d" % (sampled_bkg) + ".png" fullname = os.path.join(bkg_out, filename) patch_img.save(fullname) sampled_bkg += 1 if verbose: print "sampled a bkg patch at (x,y) center=", (x, y) sys.stdout.flush()
def score_write_patches(img_list, lab_list, target_height, target_scale, patch_size, stride, model, batch_size, neg_out, pos_out, bkg_out, preprocess=None, equalize_hist=False, featurewise_center=False, featurewise_mean=91.6, roi_cutoff=.9, bkg_cutoff=[.5, 1.], sample_bkg=True, img_ext='png', random_seed=12345, parallelized=False): '''Score image patches and write them to an external directory ''' def write_patches(img_fn, patch_dat, idx, out_dir, img_ext='png'): basename = os.path.basename(img_fn) fn_no_ext = os.path.splitext(basename)[0] if img_ext == 'png': max_val = 65535. else: max_val = 255. for i in idx: patch = patch_dat[i] patch_max = patch.max() if patch.max() != 0 else max_val patch *= max_val / patch_max patch = patch.astype('int32') mode = 'I' if img_ext == 'png' else None patch_img = toimage(patch, high=patch.max(), low=patch.min(), mode=mode) filename = fn_no_ext + "_%06d" % (i) + '.' + img_ext fullname = os.path.join(out_dir, filename) patch_img.save(fullname) rng = RandomState(random_seed) nb_roi = 0 nb_bkg = 0 for img_fn, img_lab in zip(img_list, lab_list): img = read_resize_img(img_fn, target_height=target_height) img, _ = prep.segment_breast(img) img = add_img_margins(img, patch_size / 2) patch_dat, nb_row, nb_col = sweep_img_patches( img, patch_size, stride, target_scale=target_scale, equalize_hist=equalize_hist) org_patch_dat = patch_dat.copy() if parallelized and len(patch_dat) % 2 == 1: last_patch = patch_dat[-1:, :, :] patch_dat = np.append(patch_dat, last_patch, axis=0) appended = True else: appended = False if dim_ordering == 'th': patch_X = np.zeros((patch_dat.shape[0], 3, patch_dat.shape[1], patch_dat.shape[2]), dtype='float64') patch_X[:, 0, :, :] = patch_dat patch_X[:, 1, :, :] = patch_dat patch_X[:, 2, :, :] = patch_dat else: patch_X = np.zeros((patch_dat.shape[0], patch_dat.shape[1], patch_dat.shape[2], 3), dtype='float64') patch_X[:, :, :, 0] = patch_dat patch_X[:, :, :, 1] = patch_dat patch_X[:, :, :, 2] = patch_dat if featurewise_center: patch_X -= featurewise_mean elif preprocess is not None: patch_X = preprocess(patch_X) pred = model.predict(patch_X, batch_size=batch_size) # import pdb; pdb.set_trace() if appended: pred = pred[:-1] roi_idx = np.where(pred[:, 0] < 1 - roi_cutoff)[0] bkg_idx = np.where( np.logical_and(pred[:, 0] > bkg_cutoff[0], pred[:, 0] <= bkg_cutoff[1]))[0] if sample_bkg and len(bkg_idx) > len(roi_idx): bkg_idx = rng.choice(bkg_idx, len(roi_idx), replace=False) roi_out = pos_out if img_lab == 1 else neg_out write_patches(img_fn, org_patch_dat, roi_idx, roi_out, img_ext) write_patches(img_fn, org_patch_dat, bkg_idx, bkg_out, img_ext) nb_roi += len(roi_idx) nb_bkg += len(bkg_idx) return nb_roi, nb_bkg
def sample_patches(img, roi_mask, out_dir, img_id, abn, pos, patch_size=256, pos_cutoff=.75, neg_cutoff=.35, nb_bkg=100, nb_abn=100, start_sample_nb=0, itype='calc', bkg_dir='background', calc_pos_dir='calc_mal', calc_neg_dir='calc_ben', mass_pos_dir='mass_mal', mass_neg_dir='mass_ben', verbose=False): #图像如果为阳性 if pos: #是钙化点 if itype == 'calc': #图像放入输出目录中钙化阳性目录 roi_out = os.path.join(out_dir, calc_pos_dir) else: #否则放入输出目录中肿块阳性目录 roi_out = os.path.join(out_dir, mass_pos_dir) #图像如果为阴性 else: #是钙化点 if itype == 'calc': #图像放入输出目录中钙化阴性目录 roi_out = os.path.join(out_dir, calc_neg_dir) else: #否则放入输出目录中肿块阴性目录 roi_out = os.path.join(out_dir, mass_neg_dir) #背景放到输出目录中背景目录下 bkg_out = os.path.join(out_dir, bkg_dir) #命名 basename = '_'.join([img_id, str(abn)]) #图像增加边距 img = add_img_margins(img, patch_size / 2) #掩码增加边距 roi_mask = add_img_margins(roi_mask, patch_size / 2) # Get ROI bounding box. #获取感兴趣区域边界 #掩码转为8位无符号整型 roi_mask_8u = roi_mask.astype('uint8') #获取轮廓contours ver = (cv2.__version__).split('.') if int(ver[0]) < 3: contours, _ = cv2.findContours(roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) else: _, contours, _ = cv2.findContours(roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #获取轮廓面积 cont_areas = [cv2.contourArea(cont) for cont in contours] #返回轮廓面积的索引值 idx = np.argmax(cont_areas) # find the largest contour. #获取轮廓左上角点的坐标以及宽高 rx, ry, rw, rh = cv2.boundingRect(contours[idx]) #显示详细信息为true if verbose: #将计算得到的矩以一个字典的形式返回至M M = cv2.moments(contours[idx]) try: cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) print("ROI centroid=", (cx, cy)) sys.stdout.flush() except ZeroDivisionError: cx = rx + int(rw / 2) cy = ry + int(rh / 2) print("ROI centroid=Unknown, use b-box center=", (cx, cy)) sys.stdout.flush() #实现的随机数生成通常为伪随机数生成器,为了使得具备随机性的代码最终的结果可复现,需要设置相同的种子值 rng = np.random.RandomState(12345) # Sample abnormality first.采样异常图片先进行 sampled_abn = 0 nb_try = 0 while sampled_abn < nb_abn: if nb_abn > 1: #randint用于产生基质的均匀分布的随机整数 x = rng.randint(rx, rx + rw) y = rng.randint(ry, ry + rh) nb_try += 1 if nb_try >= 1000: # 试验的Nb达到最大值,重叠截止以0.05幅度降低 print( "Nb of trials reached maximum, decrease overlap cutoff by 0.05" ) sys.stdout.flush() pos_cutoff -= .05 nb_try = 0 if pos_cutoff <= .0: # 重叠截止值达到了非阳性界限,检查感性区域掩码输入值 raise Exception("overlap cutoff becomes non-positive, " "check roi mask input.") else: x = cx y = cy # import pdb; pdb.set_trace() if nb_abn == 1 or overlap_patch_roi( (x, y), patch_size, roi_mask, cutoff=pos_cutoff): patch = img[y - patch_size / 2:y + patch_size / 2, x - patch_size / 2:x + patch_size / 2] patch = patch.astype('int32') #max返回最大值,最小值 patch_img = toimage(patch, high=patch.max(), low=patch.min(), mode='I') # patch = patch.reshape((patch.shape[0], patch.shape[1], 1)) filename = basename + "_%04d" % (sampled_abn) + ".png" fullname = os.path.join(roi_out, filename) # import pdb; pdb.set_trace() patch_img.save(fullname) sampled_abn += 1 #异常样本数量记录 nb_try = 0 if verbose: #将异常样本的块坐标显示 print("sampled an abn patch at (x,y) center=", (x, y)) sys.stdout.flush() # Sample background. sampled_bkg = start_sample_nb while sampled_bkg < start_sample_nb + nb_bkg: x = rng.randint(patch_size / 2, img.shape[1] - patch_size / 2) y = rng.randint(patch_size / 2, img.shape[0] - patch_size / 2) if not overlap_patch_roi( (x, y), patch_size, roi_mask, cutoff=neg_cutoff): patch = img[y - patch_size / 2:y + patch_size / 2, x - patch_size / 2:x + patch_size / 2] patch = patch.astype('int32') patch_img = toimage(patch, high=patch.max(), low=patch.min(), mode='I') filename = basename + "_%04d" % (sampled_bkg) + ".png" fullname = os.path.join(bkg_out, filename) patch_img.save(fullname) sampled_bkg += 1 if verbose: #将样本背景中心块坐标显示 print("sampled a bkg patch at (x,y) center=", (x, y)) sys.stdout.flush()
def sample_patches(image, roi_mask, out_dir, image_id, abn_id, pos, patch_size=256, pos_cutoff=.75, neg_cutoff=.35, nb_bkg=100, nb_abn=100, start_sample_nb=0, abn_type="calcification", bkg_dir="background", calc_pos_dir="calc_mal", calc_neg_dir="calc_ben", mass_pos_dir="mass_mal", mass_neg_dir="mass_ben", verbose=False): if pos: if abn_type == "calcification": roi_out = os.path.join(out_dir, calc_pos_dir) else: roi_out = os.path.join(out_dir, mass_pos_dir) else: if abn_type == "calcification": roi_out = os.path.join(out_dir, calc_neg_dir) else: roi_out = os.path.join(out_dir, mass_neg_dir) bkg_out = os.path.join(out_dir, bkg_dir) if not os.path.exists(roi_out): os.mkdir(roi_out) if not os.path.exists(bkg_out): os.mkdir(bkg_out) base_name = "_".join([image_id, str(abn_id)]) image = add_img_margins(image, patch_size / 2) roi_mask = add_img_margins(roi_mask, patch_size / 2) # Get ROI bounding box. roi_mask_8u = roi_mask.astype("uint8") contours, _ = cv2.findContours(roi_mask_8u.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cont_areas = [cv2.contourArea(cont) for cont in contours] idx = np.argmax(cont_areas) # find the largest contour. rx, ry, rw, rh = cv2.boundingRect(contours[idx]) if verbose: M = cv2.moments(contours[idx]) try: cx = int(M["m10"] / M["m00"]) cy = int(M["m01"] / M["m00"]) print "ROI centroid=", (cx, cy) sys.stdout.flush() except ZeroDivisionError: cx = rx + int(rw / 2) cy = ry + int(rh / 2) print "ROI centroid=Unknown, use b-box center=", (cx, cy) sys.stdout.flush() rng = np.random.RandomState(12345) # Sample abnormality first. sampled_abn = 0 nb_try = 0 while sampled_abn < nb_abn: file_name = base_name + "_%04d" % (sampled_abn) + ".png" full_path = os.path.join(roi_out, file_name) if os.path.exists(full_path): print "already exists:", full_path sampled_abn += 1 continue if nb_abn > 1: x = rng.randint(rx, rx + rw) y = rng.randint(ry, ry + rh) nb_try += 1 if nb_try >= 1000: print "Nb of trials reached maximum, decrease overlap cutoff by 0.05" sys.stdout.flush() pos_cutoff -= .05 nb_try = 0 if pos_cutoff <= .0: raise Exception("overlap cutoff becomes non-positive, " "check roi mask input.") else: x = cx y = cy # import pdb; pdb.set_trace() if nb_abn == 1 or overlap_patch_roi( (x, y), patch_size, roi_mask, cutoff=pos_cutoff): patch = image[y - patch_size / 2:y + patch_size / 2, x - patch_size / 2:x + patch_size / 2] patch = patch.astype("int32") patch_image = toimage(patch, high=patch.max(), low=patch.min(), mode="I") # patch = patch.reshape((patch.shape[0], patch.shape[1], 1)) # import pdb; pdb.set_trace() patch_image.save(full_path) sampled_abn += 1 nb_try = 0 if verbose: print "sampled an", abn_id, "patch at (x,y) center=", (x, y) sys.stdout.flush() # Sample background. sampled_bkg = start_sample_nb while sampled_bkg < start_sample_nb + nb_bkg: file_name = base_name + "_%04d" % (sampled_bkg) + ".png" full_path = os.path.join(bkg_out, file_name) if os.path.exists(full_path): print "already exists:", full_path sampled_bkg += 1 continue x = rng.randint(patch_size / 2, image.shape[1] - patch_size / 2) y = rng.randint(patch_size / 2, image.shape[0] - patch_size / 2) if not overlap_patch_roi( (x, y), patch_size, roi_mask, cutoff=neg_cutoff): patch = image[y - patch_size / 2:y + patch_size / 2, x - patch_size / 2:x + patch_size / 2] patch = patch.astype("int32") patch_image = toimage(patch, high=patch.max(), low=patch.min(), mode="I") patch_image.save(full_path) sampled_bkg += 1 if verbose: print "sampled a bkg patch at (x,y) center=", (x, y) sys.stdout.flush()