weixin_47386125
weixin_47386125
2021-06-07 12:35
采纳率: 100%
浏览 25

用贝叶斯分类器做图像分割,但是一直出错,求大神解答?

# #贝叶斯分类器

from numpy import diag,dot,prod,exp,pi,sqrt

def guass(m,v,x):
     if len(x.shape)==1:
         n,d =1,x.shape[0]
     else:
         n,d =x.shape
     S =diag(1/v)
     x =x-m
     y =exp(-0.5*diag(x,dot(S,x.T)))
     return y*(2*pi)**(-d/2.0)/(sqrt(prod(v))+1e-6)
#
from numpy import mean,var,array
# from scipy import array
class BayesClassifier(object):
     def __init__(self):
         self.labels = []
         self.mean = []
         self.var =[]
         self.n= 0

     def train(self,data,labels=None):
         if labels==None:
             labels =range(len(data))
         self.labels =labels
         self.n =len(labels)
         for c in data:
             self.mean.append(mean(c,axis =0))
             self.var.append(var(c,axis = 0))

     def classify(self,points):
         est_prob =array([guass(m,v,points)for m ,v in zip(self.mean,self.var)])
         ndx = est_prob.argmax(axis=0)
         est_labels = array([self.labels[n] for n in ndx])
         return est_labels,est_prob

分割处理

from pygraph.classes.digraph import digraph
from pygraph.algorithms.minmax import maximum_flow
from bayes import BayesClassifier

""" 
Graph Cut image segmentation using max-flow/min-cut. 
"""


def build_bayes_graph(im, labels, sigma=1e2, kappa=1):
    """    Build a graph from 4-neighborhood of pixels.
        Foreground and background is determined from
        labels (1 for foreground, -1 for background, 0 otherwise)
        and is modeled with naive Bayes classifiers."""

    m, n = im.shape[:2]

    # RGB vector version (one pixel per row)
    vim = im.reshape((-1, 3))

    # RGB for foreground and background
    foreground = im[labels == 1].reshape((-1, 3))
    background = im[labels == -1].reshape((-1, 3))
    train_data = [foreground, background]

    # train naive Bayes classifierbc
    bc =BayesClassifier()
    bc.train(train_data)

    # get probabilities for all pixels
    bc_lables, prob = bc.classify(vim)
    prob_fg = prob[0]
    prob_bg = prob[1]

    # create graph with m*n+2 nodes
    gr = digraph()
    gr.add_nodes(range(m * n + 2))

    source = m * n  # second to last is source
    sink = m * n + 1  # last node is sink

    # normalize
    for i in range(vim.shape[0]):
        vim[i] = vim[i] / (linalg.norm(vim[i]) + 1e-9)

    # go through all nodes and add edges
    for i in range(m * n):
        # add edge from source
        gr.add_edge((source, i), wt=(prob_fg[i] / (prob_fg[i] + prob_bg[i])))

        # add edge to sink
        gr.add_edge((i, sink), wt=(prob_bg[i] / (prob_fg[i] + prob_bg[i])))

        # add edges to neighbors
        if i % n != 0:  # left exists
            edge_wt = kappa * exp(-1.0 * sum((vim[i] - vim[i - 1]) ** 2) / sigma)
            gr.add_edge((i, i - 1), wt=edge_wt)
        if (i + 1) % n != 0:  # right exists
            edge_wt = kappa * exp(-1.0 * sum((vim[i] - vim[i + 1]) ** 2) / sigma)
            gr.add_edge((i, i + 1), wt=edge_wt)
        if i // n != 0:  # up exists
            edge_wt = kappa * exp(-1.0 * sum((vim[i] - vim[i - n]) ** 2) / sigma)
            gr.add_edge((i, i - n), wt=edge_wt)
        if i // n != m - 1:  # down exists
            edge_wt = kappa * exp(-1.0 * sum((vim[i] - vim[i + n]) ** 2) / sigma)
            gr.add_edge((i, i + n), wt=edge_wt)

    return gr


def cut_graph(gr, imsize):
    """    Solve max flow of graph gr and return binary
        labels of the resulting segmentation."""

    m, n = imsize
    source = m * n  # second to last is source
    sink = m * n + 1  # last is sink

    # cut the graph
    flows, cuts = maximum_flow(gr, source, sink)

    # convert graph to image with labels
    res = zeros(m * n)
    for pos, label in list(cuts.items())[:-2]:  # don't add source/sink
        res[pos] = label

    return res.reshape((m, n))



def save_as_pdf(gr, filename, show_weights=False):
    from pygraph.readwrite.dot import write
    import graphviz as gv
    dot = write(gr, weighted=show_weights)
    gvv = gv.readstring(dot)
    gv.layout(gvv, 'fdp')
    gv.render(gvv, 'pdf', filename)


def show_labeling(im, labels):
    """    Show image with foreground and background areas.
        labels = 1 for foreground, -1 for background, 0 otherwise."""

    imshow(im)
    contour(labels, [-0.5, 0.5])
    contourf(labels, [-1, -0.5], colors='b', alpha=0.25)
    contourf(labels, [0.5, 1], colors='r', alpha=0.25)
    # axis('off')
    xticks([])
    yticks([])

from scipy.misc import imresize
from PIL import Image
import numpy as np
from pylab import *
from skimage import transform


im = array(Image.open("cat.jpg"))
im =imresize(im,0.07)
print(im)
size = im.shape[:2]
print ("OK!!")

# add two rectangular training regions
labels = zeros(size)
labels[3:18, 3:18] = -1
labels[-18:-3, -18:-3] = 1
print ("OK!!")


# create graph
g = build_bayes_graph(im, labels, kappa=1)

# cut the graph
res = cut_graph(g, size)
print ("OK!!")


figure()
show_labeling(im, labels)

figure()
imshow(res)
gray()
axis('off')

show()

出现问题

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • weixin_47386125
    weixin_47386125 2021-06-07 18:26
    已采纳

    解决了y =exp(-0.5*diag(x,dot(S,x.T)))少了一个括号

    点赞 评论
  • qq_34124780
    爱晚乏客游 2021-06-07 13:33

    这句话y =exp(-0.5*diag(x,dot(S,x.T)))

    你确定下你的y是要一个数字还是要一个list?,diag(x,dot(S,x.T))这个的结果应该是一个长度大于1的一位数组,而函数exp(A)这里的A是要一个标量而不是能一个列表 或者数组。所以你可以改成下面的试试看

    y =exp(-0.5*i) for i in diag(x,dot(S,x.T))

    点赞 评论
  • QA_Assistant
    有问必答小助手 2021-06-08 11:43

    您好,我是有问必答小助手,您的问题已经有小伙伴解答了,您看下是否解决,可以追评进行沟通哦~

    如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~

    ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>>https://vip.csdn.net/askvip?utm_source=1146287632

    点赞 评论

相关推荐