我正在以下工作:我有一个商店布局,请参见下面的示例(出于GDPR的原因不能添加真实的东西,但示例应该可以解决问题),我从访客那里得到了xy坐标(当然是匿名的)
我已经在图片上放置了一个网格,以便可以看到他们在商店中走的路线。很好原点位于左下角,x&y的范围为0-100。 到目前为止,一切都很好。现在,下一步是确定货架的坐标,即图片中的矩形。有没有一种方法可以不必手动执行此操作?真实的商店布局包含900多个货架,还是我将船推得太远了?
我正在寻找的输出是一个数据框,其中包含一个货架ID和各个角的坐标。想法是在商店中创建一些热图,以查看是否存在盲点,热点,...
第二次分析也需要整数点。这个想法是创建访客点的向量,以便我们获得他们所寻找的方向。通过使用人类可以看到的范围,我将基于与整数点的交点给出“可见”产品的百分比。
谢谢! JL
答案 0 :(得分:1)
一种方法是对图像的黑色像素执行聚类。簇然后成为架子。如果架子是平行于轴的,则可以通过在每个方向上取最小值/最大值来找到矩形。效果很好:
示例代码(我将图像转换为PNG,因为它比gif更易于阅读):
library(png)
library(dbscan)
library(tidyverse)
library(RColorBrewer)
img <- readPNG("G18JU.png")
is_black <-
img %>%
apply(c(1, 2), sum) %>% #sum all color channels
{. < 2.5} %>% # we assume black if the sum is lower than 2.5 (max value is 3)
which(arr.ind=TRUE) # the indices of the black pixels
clust <- dbscan(is_black, 2) # identify clusters
rects <-
as.tibble(is_black) %>%
mutate(cluster = clust$cluster) %>% # add cluster information
group_by(cluster) %>%
## find corner points of rectangles normalized to [0, 1]
summarise(xleft = max(col) / dim(img)[2],
ybottom = 1 - min(row) / dim(img)[1],
xright = min(col) / dim(img)[2],
ytop = 1 - max(row) / dim(img)[1])
## plot the image and the rectangles
plot(c(0, 1), c(0, 1), type="n")
rasterImage(img, 0, 0, 1, 1)
for (i in seq_len(nrow(rects))) {
rect(rects$xleft[i], rects$ybottom[i], rects$xright[i], rects$ytop[i],
border = brewer.pal(nrow(rects), "Paired")[i], lwd = 2)
}
当然,这种方法还可以将其他黑色线条检测为“矩形”(例如黑色边框)。但是我想您可以轻松创建“干净”的图像。
编辑:扩展方法以查找共享黑线的架子
为了扩展该方法,使其可以分隔共享黑线的架子:
首先,以上述方式识别矩形。 然后,从图像中提取每个矩形并计算行均值。这为每个矩形提供一维图像(=线)。在此行中,像以前一样应用阈值化和聚类。聚类现在是黑线段,每个聚类的平均值对应于两个架子共享的垂直线。 要查找水平共享线,可以应用相同的过程,但是使用纵栏表示而不是横栏表示。