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()
Ejemplo n.º 3
0
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()
Ejemplo n.º 7
0
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()
Ejemplo n.º 8
0
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()
Ejemplo n.º 10
0
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()