gpt4 book ai didi

R:计算图片中的对象

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:37:03 24 4
gpt4 key购买 nike

我目前正在研究一个问题,即使用图片构建分类器来预测结果。基本上,我在图片上有对象(一个或多个),我想识别它们。因为我可以拥有一个或多个对象(并不总是相同的),所以我首先希望能够计算出我的图片上有多少个对象。我不想运行任何机器学习算法,我希望有某种方法可以尽快完成。

运行 k-means(使用颜色)使我能够将图片分成 2 个颜色组,这已经很好地分离了背景和对象。从这张图片中,我想找到一种方法来计算所有不同的“区域”。我尝试使用颜色和位置运行 k-means 以尝试一步完成所有操作,但效果不是很好,因为向 kmeans 添加位置会降低其结果。

这里是图片的示例,一旦用 kmeans 将它分成两个颜色区域:

Objects in background

显然这里有 5 个对象和 1 个背景。或者,6 个不同的区域。

我想做的是在该图片上运行一个算法,它会告诉我那个数字。我不熟悉图像处理,所以我想不出一种快速有效的方法。我想到的一种解决方案是从对象类 中取出一个像素并测试相邻像素是否属于同一类或实际上是背景类 的一部分。但这将是一个痛苦而漫长的做事方式。

我已经尝试过 blob 识别,但看起来这个算法并不适合我的需要。

我很想知道如何解决这类问题。我不介意自己编写算法代码,但我也很想知道是否有 R 包可以轻松实现这种事情。

我希望一切都足够清楚。非常感谢您!

最佳答案

更新 找到一个link to an implementation of bwlabel in the R image processing toolbox .所以以下可能不是必需的,但创建它很有趣 :-) 你应该看看那个包,因为它有其他对象分割算法(即分水岭),可能比你的 k-means 聚类的第一步更好.

如果您的分割在背景和对象之间正确标记,并且至少有一个背景像素分隔不同对象之间的边界,那么您可能需要在 R 中实现 matlab 的 bwlabel 函数。对此的解释见this SO question/answer

下面是一个不执行标记的实现(尽管可以很容易地采用它来这样做):

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 是一个递归函数,其中对于它接收的每个调用:

  1. 图像 img 的工作副本。
  2. 属于图像 img 中的对象的像素(矩阵)索引 x(行,列)的集合。
  3. 背景值bg

find.contiguous 然后继续:

  1. imgx 处的所有像素设置为 bg 颜色。这标志着我们已经访问了像素。
  2. 找到 x 中所有与 x 具有相同标签(值)的相邻像素。这会增加同一对象的区域。请注意,由于 x 不一定是单个像素,因此 x几何增长,因此,事实上,此功能并非无懈可击。
  3. 如果没有更多的邻居属于同一个对象,我们返回更新后的图像;否则,我们进行递归调用。

从对应于对象的单个像素开始,调用 find.contiguous 将扩大区域以包含对象的所有像素并返回更新后的图像,其中对象被背景替换.然后可以在循环中重复此过程,直到图像中不再有物体,因此能够生成计数。

为了说明,我假设您的二进制图像是一个名为 imgmatrix:

## 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"

关于R:计算图片中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38959470/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com