Esempio n. 1
0
# Load grain
grain = Sample(grain_ref_path).get_image()
grain = np.invert(grain)

grain[grain <
      128] = 1  # force non-grain values to have a different value than segment
grain[grain >= 128] = 255

eval_distord_segment = mt.apply_distortion(
    segment=eval_align_segment,
    polynom=polynom,
    points=transformation,
    segment_path_out="../../data/AM718/eval.generalization.png")

train_ratio_segment = mt.compute_score(segment=train_distord_segment,
                                       ebsd=grain)
eval_ratio_segment = mt.compute_score(segment=eval_distord_segment, ebsd=grain)

print("Computed score : ", score)
print("Train score: ", train_ratio_segment)
print("Eval score: ", eval_ratio_segment)

# Plot how grain/segment overlap
from matplotlib import pyplot as plt, cm

fig = plt.figure(figsize=(15, 8))
plt.imshow(eval_distord_segment, interpolation='nearest', cmap=cm.gray)
plt.imshow(grain, interpolation='nearest', cmap=cm.jet, alpha=0.5)
fig.savefig("../../data/AM718/eval.generalization.overlap.png")
Esempio n. 2
0
def __main__(args=None):

    if args is None:

        parser = argparse.ArgumentParser('Image segmentation input!')

        parser.add_argument("-seg_ref_path", type=str, required=True, help="Path to the segmented image")
        parser.add_argument("-ebsd_ref_path", type=str, required=True, help="Path to the grain image")

        parser.add_argument("-out_dir", type=str, required=True, help="Directory with input image")

        parser.add_argument("-tmp_dir", type=str, required=True, help="Directory to store intermediate results")

        parser.add_argument("-no_points", type=float, default=None, help="Ratio of image for eachpoint of the mesh")
        parser.add_argument("-no_points_step", type=float, default=50, help="Use an absolute step size instead of no_points")
        parser.add_argument("-std_pixels", type=float, default=5, help="How far are going to look around the mesh ground (% of the image dimension)")
        parser.add_argument("-max_sampling", type=int, default=2500, help="How far are going to look around the mesh ground (% of the image dimension)")
        parser.add_argument("-polynom", type=int, default=3, help="Order of the polynom to compute distorsion")

        parser.add_argument("-invert_ebsd", type=lambda x: bool(strtobool(x)), default="False", help="Put True if background is white")

        args = parser.parse_args()

    # check that grain and segment are the same slice
    id_slice = 0

    # Load segment (need to be preprocess by align.py)
    segment = Sample(args.seg_ref_path).get_image()

    # Load grain
    grain = Sample(args.ebsd_ref_path).get_image()
    if args.invert_ebsd:
        grain = np.invert(grain)  # we need the background to be black (default color for numpy transformation)

    # check that dimension match
    assert segment.shape == grain.shape, "Grain and shape must be of the same dimension"

    # compute initial score
    init_score = mt.compute_score(segment=segment, ebsd=grain)
    print("Init score : {0:.4f}".format(init_score))

    # Create initial mesh grid
    if args.no_points_step is not None:
        x = np.arange(0, segment.shape[1], args.no_points_step)
        y = np.arange(0, segment.shape[0], args.no_points_step)
    else:
        x = np.linspace(0, segment.shape[1], args.no_points)
        y = np.linspace(0, segment.shape[0], args.no_points)

    xv, yv = np.meshgrid(x, y)
    xv = xv.reshape(-1)
    yv = yv.reshape(-1)

    reduce_xv, reduce_yv = [], []
    for x, y in zip(xv, yv):

        x_left = max((x - args.no_points_step), 0)
        x_right = min((x + args.no_points_step), segment.shape[1])

        y_bottom = max((y - args.no_points_step), 0)
        y_up = min((y + args.no_points_step), segment.shape[0])

        sub_segment = segment[y_bottom:y_up, x_left:x_right]
        if sub_segment.sum() > 0:
            reduce_xv.append(x)
            reduce_yv.append(y)

    # Remove useless points:
    xv, yv = reduce_xv, reduce_yv
    mesh = np.concatenate((xv, yv)).astype(np.int32)

    initial_points = mesh

    segment = Sample(args.seg_ref_path).get_image()

    # prepare CME
    no_samples, best_score = 0, init_score
    es = cma.CMAEvolutionStrategy(initial_points, args.std_pixels)#, {'seed': 123})

    all_scores = []

    # Start black-box optimization
    while not es.stop() and no_samples < args.max_sampling:
        solutions = es.ask()

        # turn floating mesh into integer one (pixels are integer!)
        mesh_int = np.array(solutions, dtype=np.int32)

        # prepare data for multi-threading
        scores = []
        for s in mesh_int:
            xv_dist = s[:len(xv)]
            yv_dist = s[len(xv):]

            transformation = np.stack([xv, yv, xv_dist, yv_dist]).transpose()

            segment_distord = mt.apply_distortion(segment=segment, ebsd=grain,
                                                  points=transformation,
                                                  polynom=args.polynom)

            score = mt.compute_score(segment=segment_distord, ebsd=grain)
            all_scores.append(score)

            # Make the score negative as it is a minimization process
            score *= -1
            scores.append(score)

        # store no_samples
        no_samples += len(scores)

        es.tell(solutions, scores)
        es.disp()

    # Display results
    es.result_pretty()

    # retrieve the best mesh
    final_mesh = es.result.xbest

    xv_dist = final_mesh[:len(xv)]
    yv_dist = final_mesh[len(xv):]
    transformation = np.stack([xv, yv, xv_dist, yv_dist]).transpose()
    transformation = transformation.astype(np.int32)

    # Define path to save results
    out_distord = '{tmp_dir}/segment_distord.{index}.png'.format(tmp_dir=args.tmp_dir, index=id_slice)
    out_image = os.path.join(args.out_dir, "overlap.distord.slice{}.png".format(id_slice))
    out_points = os.path.join(args.out_dir, "mesh.{}.txt".format(id_slice))

    # Store points for transformation
    np.savetxt(out_points, transformation, fmt='%i')

    # Recompute best transformation
    final_segment = mt.apply_distortion(segment=segment, ebsd=grain,
                                        segment_path_out=out_distord,
                                        polynom=args.polynom,
                                        points=transformation,
                                        verbose=True)

    best_score = mt.compute_score(segment=final_segment,
                                  ebsd=grain)

    print("Final best score : {0:.4f}".format(best_score))

    # Plot how grain/segment overlap
    fig = plt.figure(figsize=(15, 8))
    plt.imshow(final_segment, interpolation='nearest', cmap=cm.gray)
    plt.imshow(grain, interpolation='nearest', cmap=cm.jet, alpha=0.5)
    fig.savefig(out_image)

    # fig, ax = plt.subplots(figsize=(15, 8))
    # ax.imshow(final_segment)
    # ax.plot(transformation[:, 2], transformation[:, 3], '.')
    # plt.show()

    # # Create ang file
    # from crystallography.tsl import OimScan
    # ang_object = OimScan("/home/fstrub/Downloads/drive-download-20180401T213826Z-001/AM718/AM718.ang")
    #
    # # Dump overlap segment/iq
    # fig = plt.figure(figsize=(15, 8))
    # plt.imshow(segment, interpolation='nearest', cmap=cm.gray)
    # plt.imshow(ang_object.iq, interpolation='nearest', cmap=cm.jet, alpha=0.5)
    # fig.savefig(os.path.join(args.tmp_dir, "overlap_seg_id.{}.png".format(id_segment)))

    return best_score, final_segment, transformation, all_scores
Esempio n. 3
0
    # Load grain
    grain = Sample(args.grain_ref_path).get_image()
    grain = np.invert(grain)

    grain[
        grain <
        128] = 1  # force non-grain values to have a different value than segment
    grain[grain >= 128] = 255

    # crop useless grain
    segment = segment[x_to_crop:, :]
    grain = grain[x_to_crop:, :]

    # compute score after cropping useless parts of grain/segment
    score = mt.compute_score(segment=segment, ebsd=grain)
    scores.append(score)

    mesh.append(transformation)

useful_mesh = []
for m in mesh:
    new_mesh = []
    for pt in m:
        if pt[0] > x_to_crop:
            new_mesh.append(pt[2:])
    useful_mesh.append(new_mesh)

useful_mesh = np.array(useful_mesh)
useful_mesh = useful_mesh.reshape([useful_mesh.shape[0], -1])
mesh_std = useful_mesh.std(axis=0)
Esempio n. 4
0
x_std = np.array(transformations)[:, :, 2].std(axis=0)
y_std = np.array(transformations)[:, :, 3].std(axis=0)

print("tx: {} +/- {}".format(np.mean(x_std), np.std(x_std)))
print("ty: {} +/- {}".format(np.mean(y_std), np.std(y_std)))

segment = Sample(root + "segment.align/segment.align.png").get_image()

f1_distance_align_distord = []
for s1 in segments:
    s = np.copy(s1)
    s[s1 <
      128] = 1  # force non-grain values to have a different value than segment
    s[s1 >= 128] = 255
    f1_distance_align_distord += [mt.compute_score(segment=segment, ebsd=s)]

print("f1_distance_align_distord: {} +/- {}".format(
    np.mean(f1_distance_align_distord), np.std(f1_distance_align_distord)))

f1_distance = []
for i, s1 in enumerate(segments):
    for j, s2 in enumerate(segments):
        if i < j:
            s = np.copy(s1)
            s[s1 <
              128] = 1  # force non-grain values to have a different value than segment
            s[s1 >= 128] = 255
            f1_distance += [mt.compute_score(segment=s, ebsd=s2)]

print("f1_distance: {} +/- {}".format(np.mean(f1_distance),
Esempio n. 5
0
def __main__(args=None):
    if args is None:
        parser = argparse.ArgumentParser('Image segmentation input!')

        parser.add_argument("-seg_ref_path",
                            type=str,
                            required=True,
                            help="Path to the segmented image")
        parser.add_argument("-ebsd_ref_path",
                            type=str,
                            required=True,
                            help="Path to the grain image")
        parser.add_argument("-ang_ref_path",
                            type=str,
                            required=True,
                            help="Path to the ang file")

        parser.add_argument("-out_dir",
                            type=str,
                            required=True,
                            help="Directory with input image")

        parser.add_argument("-tmp_dir",
                            type=str,
                            required=True,
                            help="Directory to store intermediate results")

        parser.add_argument("-no_points",
                            type=float,
                            default=None,
                            help="Ratio of image for eachpoint of the mesh")
        parser.add_argument(
            "-no_points_step",
            type=float,
            default=50,
            help="Use an absolute step size instead of no_points")
        parser.add_argument(
            "-std_pixels",
            type=float,
            default=5,
            help=
            "How far are going to look around the mesh ground (% of the image dimension)"
        )
        parser.add_argument(
            "-max_sampling",
            type=int,
            default=2500,
            help=
            "How far are going to look around the mesh ground (% of the image dimension)"
        )
        parser.add_argument("-polynom",
                            type=int,
                            default=3,
                            help="Order of the polynom to compute distorsion")

        parser.add_argument("-invert_ebsd",
                            type=lambda x: bool(strtobool(x)),
                            default="False",
                            help="Put True if background is white")
        parser.add_argument("-image_magic",
                            type=lambda x: bool(strtobool(x)),
                            default="False",
                            help="use image magick")

        args = parser.parse_args()

    # check that grain and segment are the same slice
    id_slice = 0

    # Load segment (need to be preprocess by align.py)
    segment_align = Sample(args.seg_ref_path).get_image()

    # Load grain
    ebsd = Sample(args.ebsd_ref_path).get_image()
    if args.invert_ebsd:
        ebsd = np.invert(
            ebsd
        )  # we need the background to be black (default color for numpy transformation)

    # check that dimension match
    assert segment_align.shape == ebsd.shape, "Grain and shape must be of the same dimension"

    # compute initial score
    init_score = mt.compute_score(segment=segment_align, ebsd=ebsd)
    print("Init score : {0:.4f}".format(init_score))

    # Create initial mesh grid
    if args.no_points_step is not None:
        x = np.arange(0, segment_align.shape[1], args.no_points_step)
        y = np.arange(0, segment_align.shape[0], args.no_points_step)
    else:
        x = np.linspace(0, segment_align.shape[1], args.no_points)
        y = np.linspace(0, segment_align.shape[0], args.no_points)

    xv, yv = np.meshgrid(x, y)
    xv = xv.reshape(-1)
    yv = yv.reshape(-1)

    initial_points = np.concatenate((xv, yv)).astype(np.int32)

    # prepare CME
    no_samples, best_score = 0, init_score
    es = cma.CMAEvolutionStrategy(initial_points,
                                  args.std_pixels)  # , {'seed': 123})

    all_scores = []

    # Start black-box optimization
    while not es.stop() and no_samples < args.max_sampling:
        solutions = es.ask()

        # turn floating mesh into integer one (pixels are integer!)
        mesh_int = np.array(solutions, dtype=np.int32)

        # prepare data for multi-threading
        scores = []

        i = 0
        for s in mesh_int:
            xv_dist = s[:len(xv)]
            yv_dist = s[len(xv):]

            transformation = np.stack([xv, yv, xv_dist, yv_dist]).transpose()

            ebsd_distord, _ = mt.apply_distortion_ebsd(
                segment=segment_align,
                ebsd=ebsd,
                points=transformation,
                polynom=args.polynom,
                use_img_magic=args.image_magic)

            score = mt.compute_score(segment=segment_align, ebsd=ebsd_distord)
            all_scores.append(score)

            # Make the score negative as it is a minimization process
            score *= -1
            scores.append(score)

        # store no_samples
        no_samples += len(scores)

        es.tell(solutions, scores)
        es.disp()

    # Display results
    es.result_pretty()

    # retrieve the best mesh
    final_mesh = es.result.xbest

    xv_dist = final_mesh[:len(xv)]
    yv_dist = final_mesh[len(xv):]
    transformation = np.stack([xv, yv, xv_dist, yv_dist]).transpose()
    transformation = transformation.astype(np.int32)

    # Define path to save results
    out_distord = '{tmp_dir}/ebsd_distord.{index}.png'.format(
        tmp_dir=args.tmp_dir, index=id_slice)
    out_image = os.path.join(
        args.out_dir, "overlap.distord_ebsd.slice{}.png".format(id_slice))
    out_points = os.path.join(args.out_dir, "mesh.{}.txt".format(id_slice))

    # Store points for transformation
    np.savetxt(out_points, transformation, fmt='%i')

    # Recompute best transformation
    final_ebsd, params = mt.apply_distortion_ebsd(segment=segment_align,
                                                  ebsd=ebsd,
                                                  ebsd_path_out=out_distord,
                                                  polynom=args.polynom,
                                                  points=transformation,
                                                  verbose=True)

    best_score = mt.compute_score(segment=segment_align, ebsd=final_ebsd)

    print("Final best score : {0:.4f}".format(best_score))

    # Plot how grain/segment overlap
    fig = plt.figure(figsize=(15, 8))
    plt.imshow(segment_align, interpolation='nearest', cmap=cm.gray)
    plt.imshow(final_ebsd, interpolation='nearest', cmap=cm.jet, alpha=0.5)
    fig.savefig(out_image)

    # fig, ax = plt.subplots(figsize=(15, 8))
    # ax.imshow(final_segment)
    # ax.plot(transformation[:, 2], transformation[:, 3], '.')
    # plt.show()

    # Create ang file
    ang = Ang(args.ang_ref_path)
    ang.warp(params)

    # TODO(fstrub): Allow user to define it
    phase = Phase.create_from_phase(id=2,
                                    name='Prec',
                                    formula='NiAl',
                                    phase=ang.phases[0])
    ang.add_phase(segment_align=segment_align, phase=phase)
    ang.dump_file(
        os.path.join(args.out_dir, os.path.basename(args.ang_ref_path)))

    return best_score, final_ebsd, transformation, all_scores
Esempio n. 6
0
            data = json.load(f)

        precop = data.get("precrop", None)
        [rescale_x, rescale_y] = data["rescale"]
        [tx, ty] = data["translate"]
        angle = data["angle"]

        aligner = mt.Aligner(precrop=precrop, rescale=(rescale_x, rescale_y))

        align_segment, score = aligner.apply(grain=grain,
                                             segment=segment,
                                             tx=tx,
                                             ty=ty,
                                             angle=angle)

        score = mt.compute_score(segment=align_segment, ebsd=grain)
        print("score after alignment: {}".format(score))

    ######
    # Step 2 : Distord
    ####

    if args.mesh_file is not None:
        mesh = []
        with open(args.mesh_file, "r") as file:
            for l in file.readline():
                mesh += [l.split(sep=" ")]
        mesh = np.array(mesh).transpose()

        segment_distord = mt.apply_distortion(segment=segment,
                                              points=mesh,