项目实训 No.12

项目实训 No.12

修改程序,改为一次只处理一张图片,并且只保存骨干提取图

import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage import morphology,data,color
def file_name(dir_path):
    global f_name
    global f_namelist#文件或文件夹名称(图片)

    f_name = []
    f_namelist = []

    for files in os.listdir(dir_path):
        f_namelist.append(files)

    for i in f_namelist:#分割后缀
        index = i.rfind('.')
        f_name.append(i[:index])
    print(f_namelist)
    return f_name,f_namelist
def iteration_fun(img):
#迭代法
    T = img.mean()

    while True:
        t0 = img[img < T].mean()
        t1 = img[img >= T].mean()
        t = (t0 + t1) / 2
        if abs(T - t) < 1:
            break
        T = t
    T = int(T)

    print(f"Best threshold = {T}")
    #th, img_bin = cv2.threshold(img, T, 255, 0)
    th, img_bin = cv2.threshold(img, T, 255, cv2.THRESH_BINARY_INV)
    return img_bin


def sktest3(img):
    img[img == 255] = 1
    # 实施骨架算法
    skeleton = morphology.skeletonize(img)
    return skeleton



if __name__ == "__main__":
    # img = cv2.imread("8888.png")
    R_dir_path='./image/'
    R_save_path='./result/'
    C_save_path = './compare/'
    Ske_save_path = './skeleton/'
    f_name, f_pathlist = file_name(R_dir_path)
    print(len(f_pathlist))


    for essaycounts in range(len(f_pathlist)):
        dir_path = R_dir_path + f_pathlist[essaycounts] + "/"
        ske_save_path = Ske_save_path + f_pathlist[essaycounts] + "/"

        f_name, f_namelist = file_name(dir_path)
        image_len = len(f_name)

        for imcounts in range(image_len):
            path=dir_path + f_namelist[imcounts]

            skePath = ske_save_path + f_namelist[imcounts]


            print("path:"+path)
            img = cv2.imdecode(np.fromfile(path, dtype=np.uint8), -1)
            img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

            #-------------------------------------迭代法---------------------------------#
            img_bin=iteration_fun(img)

            tPath=R_save_path+'迭代法/'+f_pathlist[essaycounts]
            if not os.path.exists(tPath):
                os.makedirs(tPath)



            tPath = Ske_save_path + '迭代法/' + f_pathlist[essaycounts]
            if not os.path.exists(tPath):
                os.makedirs(tPath)

            ske=sktest3(img_bin)
            skePath = Ske_save_path + '迭代法/' + f_pathlist[essaycounts] + "/" + f_namelist[imcounts]
            print("savePath:"+skePath)

            plt.clf()

            plt.imshow(ske, plt.cm.gray)
            plt.xticks([]), plt.yticks([])  # 隐藏坐标轴
            fig1 = plt.gcf()
            #plt.show()
            fig1.savefig(skePath, dpi=100)

修改直方图法程序

import cv2
import numpy as np
import os
import matplotlib.pyplot as plt
from skimage import morphology,data,color

def caleGrayHist(image):
    # 灰度图像的高、宽
    rows, cols = image.shape
    # 存储灰度直方图
    grayHist = np.zeros([256], np.uint64)  # 图像的灰度级范围是0~255
    for r in range(rows):
        for c in range(cols):
            grayHist[image[r][c]] += 1

    return grayHist


def threshTwoPeaks(image):
    # 计算灰度直方图
    histogram = caleGrayHist(image)

    # 找到灰度直方图的最大峰值对应得灰度值
    maxLoc = np.where(histogram == np.max(histogram))
    firstPeak = maxLoc[0][0]  # 取第一个最大的灰度值

    # 寻找灰度直方图的第二个峰值对应得灰度值
    measureDists = np.zeros([256], np.float32)
    for k in range(256):
        measureDists[k] = pow(k - firstPeak, 2) * histogram[k]
    maxLoc2 = np.where(measureDists == np.max(measureDists))
    secondPeak = maxLoc2[0][0]

    # 找到两个峰值之间的最小值对应的灰度值,作为阈值
    thresh = 0
    if firstPeak > secondPeak:  # 第一个峰值在第二个峰值右侧
        temp = histogram[int(secondPeak):int(firstPeak)]
        minLoc = np.where(temp == np.min(temp))
        thresh = secondPeak + minLoc[0][0] + 1  # 有多个波谷取左侧的波谷
    else:
        temp = histogram[int(firstPeak):int(secondPeak)]
        minLoc = np.where(temp == np.min(temp))
        thresh = firstPeak + minLoc[0][0] + 1

    # 找到阈值后进行阈值处理,得到二值图
    threshImage_out = image.copy()
    threshImage_out[threshImage_out > thresh] = 255
    threshImage_out[threshImage_out <= thresh] = 0

    return (thresh, threshImage_out)

def sktest3(img):
    img[img == 255] = 1
    # 实施骨架算法
    skeleton = morphology.skeletonize(img)
    return skeleton


if __name__ == "__main__":
    path = './image/临骨1-17/临骨1-1.png'
    print("path:" + path)
    img = cv2.imdecode(np.fromfile(path, dtype=np.uint8), -1)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    the, dst = threshTwoPeaks(img)
    th, dst = cv2.threshold(dst, 0, 255, cv2.THRESH_BINARY_INV)
    ske = sktest3(dst)

    skePath = './skeleton/直方图法/临骨1-17/临骨1-1.png'

    plt.clf()

    plt.imshow(ske, plt.cm.gray)
    plt.xticks([]), plt.yticks([])  # 隐藏坐标轴
    fig1 = plt.gcf()
    fig1.savefig(skePath, dpi=100)




修改FCM

import cv2
import numpy as np
import os

C = 2
M = 2
EPSILON = 0.001


def get_init_fuzzy_mat(pixel_count):
    global C
    fuzzy_mat = np.zeros((C, pixel_count))
    for col in range(pixel_count):
        temp_sum = 0
        randoms = np.random.rand(C - 1, 1)
        for row in range(C - 1):
            fuzzy_mat[row, col] = randoms[row, 0] * (1 - temp_sum)
            temp_sum += fuzzy_mat[row, col]
        fuzzy_mat[-1, col] = 1 - temp_sum
    return fuzzy_mat


def get_centroids(data_array, fuzzy_mat):
    global M
    class_num, pixel_count = fuzzy_mat.shape[:2]
    centroids = np.zeros((class_num, 1))
    for i in range(class_num):
        fenzi = 0.
        fenmu = 0.
        for pixel in range(pixel_count):
            fenzi += np.power(fuzzy_mat[i, pixel], M) * data_array[0, pixel]
            fenmu += np.power(fuzzy_mat[i, pixel], M)
        centroids[i, 0] = fenzi / fenmu
    return centroids


def eculidDistance(vectA, vectB):
    return np.sqrt(np.sum(np.power(vectA - vectB, 2)))


def eculid_distance(pixel_1, pixel_2):
    return np.power(pixel_1 - pixel_2, 2)


def cal_fcm_function(fuzzy_mat, centroids, data_array):
    global M
    class_num, pixel_count = fuzzy_mat.shape[:2]
    target_value = 0.0
    for c in range(class_num):
        for p in range(pixel_count):
            target_value += eculid_distance(data_array[0, p], centroids[c, 0]) * np.power(fuzzy_mat[c, p], M)
    return target_value


def get_label(fuzzy_mat, data_array):
    pixel_count = data_array.shape[1]
    label = np.zeros((1, pixel_count))

    for i in range(pixel_count):
        if fuzzy_mat[0, i] > fuzzy_mat[1, i]:
            label[0, i] = 0
        else:
            label[0, i] = 255
    return label


def cal_fuzzy_mat(data_array, centroids):
    global M
    pixel_count = data_array.shape[1]
    class_num = centroids.shape[0]
    new_fuzzy_mat = np.zeros((class_num, pixel_count))
    for p in range(pixel_count):
        for c in range(class_num):
            temp_sum = 0.
            Dik = eculid_distance(data_array[0, p], centroids[c, 0])
            for i in range(class_num):
                temp_sum += np.power(Dik / (eculid_distance(data_array[0, p], centroids[i, 0])), (1 / (M - 1)))
            new_fuzzy_mat[c, p] = 1 / temp_sum
    return new_fuzzy_mat


def fcm(init_fuzzy_mat, init_centroids, data_array):
    global EPSILON
    last_target_function = cal_fcm_function(init_fuzzy_mat, init_centroids, data_array)
    print("迭代次数 = 1, 目标函数值 = {}".format(last_target_function))
    fuzzy_mat = cal_fuzzy_mat(data_array, init_centroids)
    centroids = get_centroids(data_array, fuzzy_mat)
    target_function = cal_fcm_function(fuzzy_mat, centroids, data_array)
    print("迭代次数 = 2, 目标函数值 = {}".format(target_function))
    count = 3
    while count < 100:
        if abs(target_function - last_target_function) <= EPSILON:
            break
        else:
            last_target_function = target_function
            fuzzy_mat = cal_fuzzy_mat(data_array, centroids)
            centroids = get_centroids(data_array, fuzzy_mat)
            target_function = cal_fcm_function(fuzzy_mat, centroids, data_array)
            print("迭代次数 = {}, 目标函数值 = {}".format(count, target_function))
            count += 1
    return fuzzy_mat, centroids, target_function



if __name__ == "__main__":
    path = './image/临骨1-17/临骨1-1.png'
    print("path:" + path)
    img = cv2.imdecode(np.fromfile(path, dtype=np.uint8), -1)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    rows, cols = img.shape[:2]
    pixel_count = rows * cols
    image_array = img.reshape(1, pixel_count)

    init_fuzzy_mat = get_init_fuzzy_mat(pixel_count)
    # 初始聚类中心
    init_centroids = get_centroids(image_array, init_fuzzy_mat)
    fuzzy_mat, centroids, target_function = fcm(init_fuzzy_mat, init_centroids, image_array)
    label = get_label(fuzzy_mat, image_array)
    new_image = label.reshape(rows, cols)

    skePath = './skeleton/FCM法/临骨1-17/临骨1-1.png'

    th, r_new_image = cv2.threshold(new_image, 0, 255, cv2.THRESH_BINARY_INV)
    cv2.imencode('.png', r_new_image)[1].tofile(skePath)

修改Kmeans

import cv2
import math
import numpy as np
import os
import matplotlib.pyplot as plt
from skimage import morphology,data,color

def sktest3(img):
    img[img == 255] = 1
    # 实施骨架算法
    skeleton = morphology.skeletonize(img)
    return skeleton

if __name__ == "__main__":
    path = './image/临骨1-17/临骨1-1.png'
    print("path:" + path)
    img = cv2.imdecode(np.fromfile(path, dtype=np.uint8), -1)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img1 = img.reshape((img.shape[0] * img.shape[1], 1))
    img1 = np.float32(img1)

    # 设定一个criteria,
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)

    # 设定一个初始类中心flags
    flags = cv2.KMEANS_RANDOM_CENTERS
    # 应用K-means
    compactness, labels, centers = cv2.kmeans(img1, 2, None, criteria, 5, flags)

    #th, img2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV)

    img2 = labels.reshape((img.shape[0], img.shape[1]))



    for i in range(0,img.shape[0]):
        for j in range(0, img.shape[1]):
            if img2[i,j]==0:
                img2[i,j] =255
            elif img2[i,j] == 1:
                img2[i, j]=0

    print(img2)


    ske = sktest3(img2)

    skePath = './skeleton/kmeans/临骨1-17/临骨1-1.png'

    plt.clf()

    plt.imshow(ske, plt.cm.gray)
    plt.xticks([]), plt.yticks([])  # 隐藏坐标轴
    fig1 = plt.gcf()
    fig1.savefig(skePath, dpi=100)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值