我目前正在研究一个问题,在这个问题上,我使用图片来预测结果,从而构建了一个分类器。基本上,我在图片上有对象(一个或几个),我想识别它们。由于我可以有一个或几个对象(并不总是相同的),我首先想要能够计算出我的图片上有多少个对象。我不想运行任何机器学习算法,我希望有一些方法来尽快完成它。
运行k-方法(使用颜色)使我能够将图片分割成两个颜色组,这使得背景和对象之间已经有了很好的分离。从这张照片中,我想找到一种计算所有不同“区域”的方法。我试着运行一个k-意思是使用颜色和位置,尝试在一步完成所有,但它并不是很好的工作,因为添加位置的kmeans降低了它的结果。
下面是图片的一个示例,一旦将它与kmeans分割成两个颜色区域:
显然这里有5个物体和一个背景。或者,另外,6个不同的区域。
我想做的是在这张图片上运行一个算法,告诉我这个数字。我不熟悉图像处理,所以我想不出一种快速高效的方法。我想出的一个解决方案是从对象类中提取一个像素,并测试相邻像素是否属于同一个类,还是实际上是背景类的一部分。但这将是一种痛苦而漫长的做事方式。
我尝试过blob识别,但看起来这个算法不适合我所需要的。
我很想知道如何解决这类问题。我不介意自己编写算法,但我也想知道是否有R包可以轻松地实现这种功能。
我希望一切都足够清楚。提前谢谢你!
发布于 2016-08-15 20:14:22
Update找到了一个链接到R图像处理工具箱中bwlabel的实现。因此,下面的内容可能是不必要的,但创建起来很有趣:-)您应该看看这个包,因为它有其他对象分割算法(即分水岭),这些算法可能比k均值聚类的第一步更好。
如果您的分割在背景和目标之间的标记正确,至少有一个背景像素分隔不同对象之间的边界,那么您需要在R中实现matlab的bwlabel
函数,以了解对此的解释,参见这是如此的问题/答案。
下面是一个不执行标记的实现(尽管它可以很容易地被采用):
find.contiguous <- function(img, x, bg) {
## we need to deal with a single (row,col) matrix index
## versus a collection of them in a two column matrix separately.
if (length(x) > 2) {
lbl <- img[x][1]
img[x] <- bg
xc <- x[,1]
yc <- x[,2]
} else {
lbl <- img[x[1],x[2]]
img[x[1],x[2]] <- bg
xc <- x[1]
yc <- x[2]
}
## find all neighbors of x
x <- rbind(cbind(xc-1, yc-1),
cbind(xc , yc-1),
cbind(xc+1, yc-1),
cbind(xc-1, yc),
cbind(xc+1, yc),
cbind(xc-1, yc+1),
cbind(xc , yc+1),
cbind(xc+1, yc+1))
## that have the same label as the original x
x <- x[img[x] == lbl,]
## if there is none, we stop and return the updated image
if (length(x)==0) return(img);
## otherwise, we call this function recursively
find.contiguous(img,x,bg)
}
find.contiguous
是一个递归函数,在这个函数中,它接收到的每个调用:
img
的工作副本。x
中的对象的img
(行,col)。bg
然后,find.contiguous
继续进行:
x
在img
中的所有像素设置为bg
颜色。这标志着我们已经访问了像素。x
的所有相邻像素,这些像素具有与x
中相同的标签(值)。这将增长同一对象的区域。请注意,由于x
不一定是单个像素,x
以几何方式增长,因此,实际上,这个函数不是懒散的。从与对象对应的单个像素开始,对find.contiguous
的调用将使该区域增长到包含该对象的所有像素,并返回一个更新的图像,其中对象将被背景替换。然后可以在循环中重复此过程,直到图像中没有更多的对象,从而生成计数。
为了说明,我假设您的二进制映像是一个名为matrix
img
的图像。
## set the background pixel value
bg <- 0
## set the object pixel value
obj <- 1
## pad image so that the edge is background, this is necessary because
## the neighborhood generated in find.contiguous must lie strictly within
## the image
tmp <- matrix(bg,nrow=nrow(img)+2,ncol=ncol(img)+2)
tmp[2:(nrow(img)+1),2:(ncol(img)+1)] <- img
img <- tmp
## initialize the count to zero
count <- 0
## get all pixel coordinates that are objects
x <- which(img==obj, arr.ind=TRUE)
## loop until there are no more pixels that are objects
while (length(x) > 0) {
## choose a single (e.g., first) pixel location. This belongs to the current
## object that we will grow and remove from the image using find.contiguous
if (length(x) > 2) {
x <- x[1,]
}
## increment the count
count <- count + 1
## make the call to remove the object from img
img <- find.contiguous(img, x, bg)
## find the remaining pixel locations belonging to objects
x <- which(img==obj, arr.ind=TRUE)
}
你的答案是count
。在上一链接中的示例数据上运行此操作:
img <- as.matrix(read.table(text="
0 0 0 0 0 1 1 1 0 0
0 1 0 1 0 0 1 1 0 0
0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 1
0 0 1 1 1 1 0 0 1 1", header=FALSE))
我们得到:
print(paste("number of objects: ",count))
##[1] "number of objects: 4"
发布于 2016-08-15 20:29:20
我不是图片识别方面的专家,所以我的方法可能会失败。如果您的对比是好的,并且所有的矩形都是水平对齐的,那么您也许可以尝试以下方法:
如果这有效的话,你也有矩形的中心。希望这能帮上忙..。
https://stackoverflow.com/questions/38959470
复制相似问题