在R中提取特定的PCB颜色以进行缺陷分类

问题描述 投票:0回答:1

假设我们有以下图片,其中包含 PCB 缺陷(称为缺孔缺陷):

我的项目中需要识别的缺陷列表是:

为此,我需要提取与缺陷类别相关的颜色。

我知道使用 R ,我们可以做到:

library(colorfindr)
img_path="C:/Users/Rayane_2/Desktop/Data/PCB1/PCB/images/Mouse_bite/01_mouse_bite_04.jpg"
colorfindr::get_colors(img_path,top_n=20)
# A tibble: 20 × 3
   col_hex col_freq col_share
   <chr>      <int>     <dbl>
 1 #005B0C    31106   0.00646
 2 #005B0E    29117   0.00605
 3 #01590B    27768   0.00577
 4 #005A0B    24135   0.00502
 5 #015C0D    23771   0.00494
 6 #00580A    22397   0.00465
 7 #005B0B    21529   0.00447
 8 #00560F    21476   0.00446
 9 #005A0D    21324   0.00443
10 #025A0C    21191   0.00440
11 #01590D    21026   0.00437
12 #005709    20009   0.00416
13 #00580E    19063   0.00396
14 #005909    18666   0.00388
15 #015C0F    18450   0.00383
16 #025A0E    17979   0.00374
17 #015710    16621   0.00345
18 #01590F    16619   0.00345
19 #00580C    16546   0.00344
20 #005A0A    15614   0.00324

从缺陷类型图片中,我看到有 3 种颜色可以区分这些缺陷。

我需要识别这 3 个并从 tibble 数据集中提取。

r machine-learning image-processing computer-vision feature-extraction
1个回答
0
投票

这个问题很有趣,我们可以尝试不同的特征,从手动、手工制作(从简单到复杂的特征和不同的机器学习模型)到自动提取的特征(例如,使用深度学习深度神经网络模型)。

让我们尝试一个非常简单的仅基于颜色的功能。

我们首先使用

k
聚类算法将图像RGB颜色值聚类为
k=3
组(例如
kmeans
),并使用函数
k
获得
get.color.clusters()
颜色聚类中心,如下所示(我们需要从十六进制颜色值中提取红色、绿色、蓝色值)。

然后我们将使用

kmeans
模型来预测图像的每个像素所属的颜色簇,然后计算图像中属于颜色簇的像素的比例作为特征(因此我们将具有
k
特征)。因此,对于
k=3
集群,我们的数据框将如下所示:

         cluster1 cluster2 cluster3 class (label)

image1      0.6       0.3      0.1     missing holes

这意味着对于缺失的孔图像1,我们分别有 60%、30% 和 10% 的像素属于簇 1、2 和 3。

现在,该数据集将用于训练(二元)分类器,如果我们假设同一缺陷类别的颜色簇比例具有相似的模式,则分类器将执行下降工作。

这是我们仅用于 2 个类别的两组图像:

缺孔

老鼠咬伤

现在,让我们提取颜色簇比例特征,并尝试使用 RBF 核的 SVM 分类器来对缺陷类别进行分类和预测。

find_cluster_kmeans <- function(cl, x) { # predict the color cluster a pixel belongs to
  return (which.min(apply(cl$centers, 1, function(y) sum((y-x)^2))))
}

extract.color.features <- function(img_path, cl) {
  col_df <- colorfindr::get_colors(img_path, top_n=20)
  cols <- as.data.frame(t(do.call(rbind, lapply(col_df['col_hex'], col2rgb))))
  col_cluster <- apply(cols, 1, function(x) find_cluster_kmeans(cl, x))
  col_df <- cbind(col_df, cols, col_cluster=col_cluster)
  col_df <- col_df[c('col_cluster', 'col_share')]
  df_feat <- aggregate(col_df$col_share, list(col_df$col_cluster), FUN=sum) # group by color clusters and sum proportions
  names(df_feat) <- c('col_clust', 'prop')
  for (i in 1:(nrow(cl$centers))) { # ensure that all color clusters are present
    if (nrow(df_feat[df_feat$col_clust == i,]) == 0) {
      df_feat <- rbind(df_feat, data.frame(col_clust=i, prop=0))
    }
  }
  df_feat$prop <- df_feat$prop / sum(df_feat$prop) # normalize
  return(df_feat)
}

get.color.clusters <- function(k=3, top_n=50) {
  col_df <- NULL
  for (folder in c('missing_hole', 'Mouse_bite')) {
    img_path <- list.files(folder,".png", full.names = T)
    cdf <- do.call(rbind, lapply(img_path, function(p) colorfindr::get_colors(p,top_n=top_n)))
    col_df <- rbind(col_df, cdf)
  }
  cols <- as.data.frame(t(do.call(rbind, lapply(col_df['col_hex'], col2rgb))))
  cl <- kmeans(cols, k)
  print(cl$center)
  return (cl)
}

library(colorfindr)
set.seed(12)
k <- 3 # 3 color clusters
cl <- get.color.clusters(k)
df <- NULL
for (cls in c('missing_hole', 'Mouse_bite')) {
  img_path <- list.files(cls,".png", full.names = T)
  df_feat <- NULL
  for (img in img_path) {
    #print(img)
    df_feat <- rbind(df_feat, extract.color.features(img, cl)$prop)
  }
  df_feat <- as.data.frame(df_feat)
  df_feat$class <- cls
  df <- rbind(df, df_feat)
}
names(df)[1:k] <- paste0('cluster', 1:k)
df$class <- as.factor(df$class)
df    # each row corrspeonds to an image and each column to a color cluster
#     cluster1   cluster2   cluster3        class
#1 0.318473896 0.68152610 0.00000000 missing_hole
#2 0.984514797 0.01548520 0.00000000 missing_hole
#3 0.967479675 0.03252033 0.00000000 missing_hole
#4 0.010911326 0.80282772 0.18626095   Mouse_bite
#5 0.008364049 0.96257443 0.02906153   Mouse_bite
#6 0.446066380 0.55393362 0.00000000   Mouse_bite

library(e1071)
svmfit = svm(class ~ ., data = df, kernel = "radial", cost = 1, scale = FALSE, type='C')
print(svmfit)
plot(svmfit, df, cluster1 ~ cluster2, fill=TRUE, alpha=0.2)
df$prdicted <- predict(svmfit, df)
df
#     cluster1   cluster2   cluster3        class     prdicted
#1 0.318473896 0.68152610 0.00000000 missing_hole   Mouse_bite
#2 0.984514797 0.01548520 0.00000000 missing_hole missing_hole
#3 0.967479675 0.03252033 0.00000000 missing_hole missing_hole
#4 0.010911326 0.80282772 0.18626095   Mouse_bite   Mouse_bite
#5 0.008364049 0.96257443 0.02906153   Mouse_bite   Mouse_bite
#6 0.446066380 0.55393362 0.00000000   Mouse_bite   Mouse_bite

理想情况下,我们应该在一定比例的数据集上进行训练,并在保留的数据集上评估分类器以实现通用性。

现在颜色簇比例特征非常幼稚,并且可能不会很好地执行,那么您可以尝试提取 HOG、SIFT、SURF、BRISK、BRIEF 等特征,并使用相应的描述符作为 ML 分类器的特征向量。

最后,为了获得最佳性能,我们可以使用深度神经网络在不同层实现自动特征生成,但在这种情况下,我们需要有相当大量的训练图像(通过数据增强增加训练数据集大小)或使用在一些标准的再训练网络(例如 Vgg-15)之上进行迁移学习。

© www.soinside.com 2019 - 2024. All rights reserved.