def get_decile_widths(binary_mask, scale):
    mask_T = binary_mask.T

    tip_index = get_index_of_tip(mask_T)
    shoulder_index = get_index_of_shoulder(mask_T)
    # print("t", tip_index, "s", shoulder_index)
    decile = int((shoulder_index - tip_index) / 10)
    decile_indices = [
        i for i in range(tip_index, tip_index + decile * 10, decile)
    ] + [shoulder_index - 1]
    decile_widths = [count_white_pixels(mask_T[i]) for i in decile_indices]
    mm_per_pixel = pixel_to_mm(scale)
    decile_widths_mm = [round(i * mm_per_pixel, 2) for i in decile_widths]

    # shoulder to tip, that's why it's reversed here.
    return decile_widths_mm[::-1]
示例#2
0
def get_histogram_data(src, diff_thresh=25):
    diff_too_big_count = 0
    total_count = 0
    regr = load("tip-mask-model.joblib")
    pairs = get_mask_pairs(src)
    data = []
    for pair in pairs:
        total_count += 1
        raw = pair["with-tips"]
        training = pair["without-tips"]

        raw_mask = cv2.imread(raw, cv2.IMREAD_GRAYSCALE)
        training_mask = cv2.imread(training, cv2.IMREAD_GRAYSCALE)

        attributes = get_attributes_from_filename(raw)
        scale = attributes.get("Scale", None)
        mm_per_px = pixel_to_mm(scale)

        tip_index = tip_mask_ml(raw_mask, regr, mm_per_px)

        detipped_length = get_length(training_mask)

        length_diff = round(tip_index[0]) - detipped_length

        if abs(length_diff) > diff_thresh:
            diff_too_big_count += 1
            raw_length = get_length(raw_mask)
            print(">>>>>>>>>>>>>>>>")
            print(f"tip mask diff > {diff_thresh} px", raw)
            print("with-tip -> without-tip diff: ",
                  raw_length - detipped_length)
        data.append(length_diff)
    print(
        f"diff > {diff_thresh}px in {diff_too_big_count} out of {total_count} cases."
    )
    return data
示例#3
0
def tip_mask(src, model, visualize=False):
    """
    mask the tips of the straightened carrots

    Args:
        src (str) - absolute path to the binary mask
        visualize (bool) - only visualize the masking
    """

    # if not dest:
    dest = src.split(STRAIGHTENED_MASKS_DIR)[0]
    dest = os.path.join(dest, DETIPPED_MASKS_DIR)
    if os.path.exists(dest):
        shutil.rmtree(dest)

    if not os.path.exists(dest):
        os.makedirs(dest)

    for file in os.listdir(src):
        print(file)
        src_filepath = os.path.join(src, file)
        dest_filepath = os.path.join(dest, file)

        mask = cv2.imread(src_filepath, cv2.IMREAD_GRAYSCALE)

        attributes = get_attributes_from_filename(src_filepath)
        scale = attributes.get("Scale", None)
        mm_per_px = pixel_to_mm(scale)

        if mask is None:
            msg = "File %s is empty!" % src_filepath
            click.secho(msg, fg="red")
            continue

        # get index from ml model
        try:
            tip_index = tip_mask_ml(mask, model, mm_per_px)
        except Exception as e:
            click.secho(file, fg="red")
            print(e)
            tip_index = [0]
        tip_index = int(tip_index[0])
        # print(tip_index)
        # print(mask.shape[1])
        tip_index = mask.shape[1] - tip_index

        # get index based on threshold
        # tip_index = find_tip_pseudo_dynamic(mask, pure=True)
        # tip_index_advanced = find_tip_pseudo_dynamic(mask, pure=False)

        # if tip_index_advanced > 0:
        #     crop_index = tip_index_advanced
        # else:
        #     crop_index = tip_index
        crop_index = tip_index

        if visualize:
            # paint only
            tip = mark_start_of_tail(mask.copy(), tip_index, [0, 0, 255])
            # tip = mark_start_of_tail(tip, tip_index_advanced, [0, 255, 0])
            # print(dest)
            write_file(tip, dest, file)
            continue

        else:
            # crop + buffer + wirte
            mask = mask[:, crop_index:]

            black_col = np.zeros((mask.shape[0], 10), dtype=np.uint8)
            mask = np.hstack([black_col, mask])

            # another round of contour reduction to remove dangling white pixels
            mask = reduce_to_contour(mask, minimize=False)

            cv2.imwrite(dest_filepath, mask)

        old_tip_index = get_index_of_tip(mask.T)
        tip_length = crop_index - old_tip_index
        if tip_length < 0:
            tip_length = 0
        tip_biomass = get_biomass(mask[:, old_tip_index:crop_index])
        new_filepath = append_or_change_filename(dest_filepath, "TipLength",
                                                 None, tip_length)
        append_or_change_filename(new_filepath, "TipBiomass", None,
                                  tip_biomass)
示例#4
0
def run(src):
    start = timeit.default_timer()
    pairs = get_mask_pairs(src)

    # pixel müssen vergleichbar sein.
    data = []
    for pair in pairs:
        raw = pair["with-tips"]
        training = pair["without-tips"]

        # print(raw)
        attributes = get_attributes_from_filename(raw)
        scale = attributes.get("Scale", None)
        mm_per_px = pixel_to_mm(scale)
        # print(mm_per_px)

        raw_mask = cv2.imread(raw, cv2.IMREAD_GRAYSCALE)
        training_mask = cv2.imread(training, cv2.IMREAD_GRAYSCALE)

        # reverse, so the thick end is at 0
        width_array = get_width_array_mm(raw_mask, mm_per_px)[::-1]
        # print(width_array)
        normalized_width_array = normalize_width_array(width_array)

        # length of raw carrot
        # raw_length = get_length(raw_mask)
        # print("length", raw_length)

        # length of detipped carrot
        detipped_length = get_length(training_mask)
        # print("detipped length", detipped_length)

        # difference in length
        # length_diff = raw_length - detipped_length

        # white_index_raw = get_index_first_white_pixel(raw_mask)

        # tip_index = white_index_raw + length_diff

        # because the widths are reversed
        tip_index = detipped_length

        data.append(
            {"tip_index": tip_index, "normalized_widths": normalized_width_array}
        )

    # resampling sagt Gilles...
    equalized_data = equalize_lengths(data)

    X = [d["normalized_widths"] for d in equalized_data]
    y = [d["tip_index"] for d in equalized_data]

    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

    # linreg = LinearRegression().fit(X_train, y_train)

    # print('R-squared score (training): {:.3f}'
    #  .format(linreg.score(X_train, y_train)))
    # print('R-squared score (test): {:.3f}'
    #     .format(linreg.score(X_test, y_test)))

    regr = RandomForestRegressor(max_depth=5, random_state=0, n_estimators=10)
    regr.fit(X_train, y_train)
    print("score", regr.score(X_test, y_test))

    # regr.predict([[feature1, feature2]])

    dump(regr, "tip-mask-model.joblib")
    print("model dumped")
    stop = timeit.default_timer()
    print(f"training: {stop - start}")
def convert_surface_to_mm2(scale, surface_px):
    mm_per_pixel = pixel_to_mm(scale)
    mm2_per_pixel = mm_per_pixel**2
    surface_mm2 = mm2_per_pixel * surface_px
    return round(surface_mm2, 4)
def convert_length_to_mm(scale, length_px):
    mm_per_pixel = pixel_to_mm(scale)
    length_mm = length_px * mm_per_pixel
    return round(length_mm, 4)