叶片形状分类

作者: lizg | 来源:发表于2019-04-07 23:28 被阅读8次
    import skimage,math,numpy
    from sklearn.decomposition import PCA
    from skimage import io,transform,measure
    from skimage.color import rgb2gray
    from skimage.filters import threshold_otsu, threshold_sauvola
    
    path='F:\数据挖掘原理\dataset\题目三\圆叶\*.jpg'
    coll1 = io.ImageCollection(path)
    path='F:\数据挖掘原理\dataset\题目三\尖叶\*.jpg'
    coll2 = io.ImageCollection(path)
    
    feature1=[]
    #提取圆叶的特征值
    for num in range(0,len(coll1)):
        #转换为二值图
        origin_img=coll1[num]
        origin_img = transform.rescale(origin_img, 0.1)
        gray_img=rgb2gray(origin_img)
        otsu_threshold = threshold_otsu(gray_img)
        gray_img = skimage.img_as_ubyte(gray_img)
        bin_image = gray_img > otsu_threshold
        
        labels=measure.label(bin_image)#连通区域标记
        
        repr=measure.regionprops(labels)#获取连通域的特征属性
        
        max_area=0
        yezi=repr[0]
        for i in range(0,len(repr)):
            if(repr[i].area>=max_area):
                max_area=repr[i].area
                yezi=repr[i]
        Cir_ex=(4*math.pi*max_area)/(yezi.perimeter*yezi.perimeter)
        Rec_ex=yezi.extent
        #得到特征圆形度和矩形度
        
        a=numpy.zeros([bin_image.shape[1]])
        bin_image1=numpy.row_stack((a,bin_image,a))
        a1=numpy.zeros([bin_image1.shape[0]])
        a1=a1.T
        bin_image1=numpy.c_[a1,bin_image1,a1]
        max_height=0
        outline=[]
        for y in range(1,bin_image1.shape[0]-2):
            for x in range(1,bin_image1.shape[1]-1):
                if((bin_image1[y][x-1]==0 and bin_image1[y][x]==1)or(bin_image1[y][x]==1 and bin_image1[y][x+1]==0) or( bin_image1[y-1][x]==0 and bin_image1[y][x]==1 )or(bin_image1[y+1][x]==0 and bin_image1[y][x]==1)):
                    outline.append([x,y])                                                     # 提取边缘坐标
                    
        for i in range(0,len(outline)):
            for j in range(i+1,len(outline)):
                length=math.sqrt((outline[j][0]-outline[i][0])*(outline[j][0]-outline[i][0])+(outline[j][1]-outline[i][1])*(outline[j][1]-outline[i][1]))
                if(length>max_height):
                    max_height=length                                                        # 提取叶子的最大长度
                    x1=outline[i][0]
                    x2=outline[j][0]
                    y1=outline[i][1]
                    y2=outline[j][1]
        max_width=0
        min=math.fabs((outline[1][0]-outline[0][0])*(x2-x1)+(outline[1][1]-outline[0][1])*(y2-y1))
        for i in range(0,len(outline)-1):
            for j in range(i+1,len(outline)):
                if(math.fabs((outline[j][0]-outline[i][0])*(x2-x1)+(outline[j][1]-outline[i][1])*(y2-y1))<min):
                    min=math.fabs((outline[j][0]-outline[i][0])*(x2-x1)+(outline[j][1]-outline[i][1])*(y2-y1))
                    width=math.sqrt((outline[j][0]-outline[i][0])*(outline[j][0]-outline[i][0])+(outline[j][1]-outline[i][1])*(outline[j][1]-outline[i][1]))
                    if(width>max_width):
                        max_width=width                                                      # 提取叶子的最大宽度 
                        x3=outline[i][0]
                        x4=outline[j][0]
                        y3=outline[i][1]
                        y4=outline[j][1]
                        
        wh_cp=max_width/max_height
        feature1.append([Cir_ex,Rec_ex,wh_cp])
    
    feature2=[]
    #提取尖叶的特征值
    for num in range(0,len(coll2)):
        #转换为二值图
        origin_img=coll2[num]
        origin_img = transform.rescale(origin_img, 0.1)
        gray_img=rgb2gray(origin_img)
        otsu_threshold = threshold_otsu(gray_img)
        gray_img = skimage.img_as_ubyte(gray_img)
        bin_image = gray_img > otsu_threshold
        
        labels=measure.label(bin_image)#连通区域标记
        
        repr=measure.regionprops(labels)#获取连通域的特征属性
        
        max_area=0
        yezi=repr[0]
        for i in range(0,len(repr)):
            if(repr[i].area>=max_area):
                max_area=repr[i].area
                yezi=repr[i]
        Cir_ex=(4*math.pi*max_area)/(yezi.perimeter*yezi.perimeter)
        Rec_ex=yezi.extent
        #得到特征圆形度和矩形度
        
        a=numpy.zeros([bin_image.shape[1]])
        bin_image1=numpy.row_stack((a,bin_image,a))
        a1=numpy.zeros([bin_image1.shape[0]])
        a1=a1.T
        bin_image1=numpy.c_[a1,bin_image1,a1]
        max_height=0
        outline=[]
        for y in range(1,bin_image1.shape[0]-2):
            for x in range(1,bin_image1.shape[1]-1):
                if((bin_image1[y][x-1]==0 and bin_image1[y][x]==1)or(bin_image1[y][x]==1 and bin_image1[y][x+1]==0) or( bin_image1[y-1][x]==0 and bin_image1[y][x]==1 )or(bin_image1[y+1][x]==0 and bin_image1[y][x]==1)):
                    outline.append([x,y])                                                     # 提取边缘坐标
                    
        for i in range(0,len(outline)):
            for j in range(i+1,len(outline)):
                length=math.sqrt((outline[j][0]-outline[i][0])*(outline[j][0]-outline[i][0])+(outline[j][1]-outline[i][1])*(outline[j][1]-outline[i][1]))
                if(length>max_height):
                    max_height=length                                                        # 提取叶子的最大长度
                    x1=outline[i][0]
                    x2=outline[j][0]
                    y1=outline[i][1]
                    y2=outline[j][1]
        max_width=0
        min=math.fabs((outline[1][0]-outline[0][0])*(x2-x1)+(outline[1][1]-outline[0][1])*(y2-y1))
        for i in range(0,len(outline)-1):
            for j in range(i+1,len(outline)):
                if(math.fabs((outline[j][0]-outline[i][0])*(x2-x1)+(outline[j][1]-outline[i][1])*(y2-y1))<min):
                    min=math.fabs((outline[j][0]-outline[i][0])*(x2-x1)+(outline[j][1]-outline[i][1])*(y2-y1))
                    width=math.sqrt((outline[j][0]-outline[i][0])*(outline[j][0]-outline[i][0])+(outline[j][1]-outline[i][1])*(outline[j][1]-outline[i][1]))
                    if(width>max_width):
                        max_width=width                                                      # 提取叶子的最大宽度 
                        x3=outline[i][0]
                        x4=outline[j][0]
                        y3=outline[i][1]
                        y4=outline[j][1]
                        
        wh_cp=max_width/max_height
        feature2.append([Cir_ex,Rec_ex,wh_cp])
    
    #特征主成分分析
    feature=feature1+feature2
    pca=PCA(n_components=3)
    pca.fit(feature)
    weight=pca.explained_variance_ratio_
    print(pca.explained_variance_ratio_)
    
    #得到圆叶判别公式
    #Fx=特征1*权重+特征2*权重+特征3*权重
    Fx1=[]
    for fe in feature1:
        Fx=fe[0]*weight[0]+fe[1]*weight[1]+fe[2]*weight[2]
        Fx1.append(Fx)
    m1=numpy.max(Fx1)
    m2=numpy.min(Fx1)
    print(Fx1)
    print(m1)
    print(m2)
    
    #尖叶叶特征主成分分析
    pca=PCA(n_components=3)
    pca.fit(feature2)
    #得到尖叶判别公式
    #Fx=特征1*权重+特征2*权重+特征3*权重
    Fx2=[]
    for fe in feature2:
        Fx=fe[0]*weight[0]+fe[1]*weight[1]+fe[2]*weight[2]
        Fx2.append(Fx)
    print(Fx2)
    l1=numpy.max(Fx2)
    l2=numpy.min(Fx2)
    print(l1)
    print(l2)
    
    path='F:\数据挖掘原理\dataset\题目三\叶子\*.jpg'
    coll3 = io.ImageCollection(path)
    #提取叶子的特征值
    i=1
    j=1
    for num in range(0,len(coll3)):
        #转换为二值图
        origin_img=coll3[num]
        origin_img = transform.rescale(origin_img, 0.1)
        gray_img=rgb2gray(origin_img)
        otsu_threshold = threshold_otsu(gray_img)
        gray_img = skimage.img_as_ubyte(gray_img)
        bin_image = gray_img > otsu_threshold
        
        labels=measure.label(bin_image)#连通区域标记
        
        repr=measure.regionprops(labels)#获取连通域的特征属性
        
        max_area=0
        yezi=repr[0]
        for i in range(0,len(repr)):
            if(repr[i].area>=max_area):
                max_area=repr[i].area
                yezi=repr[i]
        Cir_ex=(4*math.pi*max_area)/(yezi.perimeter*yezi.perimeter)
        Rec_ex=yezi.extent
        #得到特征圆形度和矩形度
        
        a=numpy.zeros([bin_image.shape[1]])
        bin_image1=numpy.row_stack((a,bin_image,a))
        a1=numpy.zeros([bin_image1.shape[0]])
        a1=a1.T
        bin_image1=numpy.c_[a1,bin_image1,a1]
        max_height=0
        outline=[]
        for y in range(1,bin_image1.shape[0]-2):
            for x in range(1,bin_image1.shape[1]-1):
                if((bin_image1[y][x-1]==0 and bin_image1[y][x]==1)or(bin_image1[y][x]==1 and bin_image1[y][x+1]==0) or( bin_image1[y-1][x]==0 and bin_image1[y][x]==1 )or(bin_image1[y+1][x]==0 and bin_image1[y][x]==1)):
                    outline.append([x,y])                                                     # 提取边缘坐标
                    
        for i in range(0,len(outline)):
            for j in range(i+1,len(outline)):
                length=math.sqrt((outline[j][0]-outline[i][0])*(outline[j][0]-outline[i][0])+(outline[j][1]-outline[i][1])*(outline[j][1]-outline[i][1]))
                if(length>max_height):
                    max_height=length                                                        # 提取叶子的最大长度
                    x1=outline[i][0]
                    x2=outline[j][0]
                    y1=outline[i][1]
                    y2=outline[j][1]
        max_width=0
        min_=math.fabs((outline[1][0]-outline[0][0])*(x2-x1)+(outline[1][1]-outline[0][1])*(y2-y1))
        for i in range(0,len(outline)-1):
            for j in range(i+1,len(outline)):
                if(math.fabs((outline[j][0]-outline[i][0])*(x2-x1)+(outline[j][1]-outline[i][1])*(y2-y1))<min_):
                    min_=math.fabs((outline[j][0]-outline[i][0])*(x2-x1)+(outline[j][1]-outline[i][1])*(y2-y1))
                    width=math.sqrt((outline[j][0]-outline[i][0])*(outline[j][0]-outline[i][0])+(outline[j][1]-outline[i][1])*(outline[j][1]-outline[i][1]))
                    if(width>max_width):
                        max_width=width                                                      # 提取叶子的最大宽度 
                        x3=outline[i][0]
                        x4=outline[j][0]
                        y3=outline[i][1]
                        y4=outline[j][1]
                        
        wh_cp=max_width/max_height
        if((Cir_ex*weight[0]+Rec_ex*weight[1]+wh_cp*weight[2])>=m2 and (Cir_ex*weight[0]+Rec_ex*weight[1]+wh_cp*weight[2])<=m1):
            print("圆叶",end='')
            str1="yuan"+str(i)+".jpg"
            io.imsave("F:\数据挖掘原理\image_classification_demo-master\叶子\圆叶\{0}".format(str1),coll3[num])
            i=i+1
        elif((Cir_ex*weight[0]+Rec_ex*weight[1]+wh_cp*weight[2])>=l2 and (Cir_ex*weight[0]+Rec_ex*weight[1]+wh_cp*weight[2])<=l1):
            print("尖叶",end=' ')
            str2="jian"+str(j)+".jpg"
            io.imsave("F:\数据挖掘原理\image_classification_demo-master\叶子\尖叶\{0}".format(str2),coll3[num])
            j=j+1
        else:
            print("无法识别")
    

    相关文章

      网友评论

        本文标题:叶片形状分类

        本文链接:https://www.haomeiwen.com/subject/vtqyiqtx.html