首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不规则物体的Opencv颜色分类

不规则物体的Opencv颜色分类
EN

Stack Overflow用户
提问于 2020-11-15 23:32:42
回答 1查看 286关注 0票数 0

我正在尝试创建一个算法,使用python和OpenCV来对一部分棉花进行分类,并预定义一些白色色调。我是计算机视觉专业的新手,很难让它发挥作用。

我读过CIE L.A.B是最好的颜色空间,因为它不受硬件(如相机或显示器)的影响,所以我认为比较白色色调是最好的选择(如果我错了,请纠正我)。

我第一次使用了一些白色调的平方图像,并根据预先确定的白色调计算了α值,根据白度的分类进行分类。当我开始使用真正的棉花形象时,我的问题就开始了。

我使用了一个掩码来过滤我想要分类的白色调的范围,只得到图像上的棉花,但是图像的其余部分(没有被蒙版捕捉到)以黑色像素为单位,而这些黑色像素会干扰我的颜色检查。

我尝试了很多事情:忽略黑色像素,重塑图像(将棉花图像转换成分散所有图像区域),但没有成功。我还试着计算图像的中心,或者画一个正方形,得到一些区域的棉花图像,并对其进行切割和分析,但我意识到我需要对所有的棉花表面进行分析。

我的问题是,我想知道是否有人知道如何处理这个问题中附加的棉花图像(完全)忽略或删除黑色像素。

在这里,我的脚本的结果映像:

掩码和轮廓检测的结果

在我的剧本上面:

代码语言:javascript
复制
import cv2
import numpy as np
import numpy.ma as ma
import argparse
import colour

def getContours(img):
    contours, Hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

    contours_poly = [None]*len(contours)
    boundRect = [None]*len(contours)
    centers = [None]*len(contours)
    radius = [None]*len(contours)

    for i, cnt in enumerate(contours):

        area = cv2.contourArea(cnt)

        if area>30:
            contours_poly[i] = cv2.approxPolyDP(cnt, 3, True)
            boundRect[i] = cv2.boundingRect(contours_poly[i])
            centers[i], radius[i] = cv2.minEnclosingCircle(contours_poly[i])

            # print(area)

            perc = 0

    
            cv2.drawContours(imgContour, cnt, -1, (255,255,255),3)
            peri = cv2.arcLength(cnt, True)
            # approx = cv2.approxPolyDP(cnt, 0.02*peri,True) #retorna os cantos da forma
            approx = cv2.approxPolyDP(cnt, 0.02*peri,True) #retorna os cantos da forma
            x,y,w,h = cv2.boundingRect(approx)
            #cv2.rectangle(imgContour, (x,y),(x+w,y+h),(0,255,0),2)
            #cv2.circle(imgContour, (int(centers[i][0]), int(centers[i][1])), int(radius[i]-(radius[i]*0.5)), (255,0,0), 2)
            pt1 = (int(boundRect[i][0]), int(boundRect[i][1]))
            pt2 = (int(boundRect[i][0]+boundRect[i][2]), int(boundRect[i][1]+boundRect[i][3]))

            # pt1 = (int(pt1[0] + pt1[0]*perc), int(pt1[1] + pt1[1]*perc))
            # pt2 = (int(pt2[0] - pt2[0]*perc), int(pt2[1] - pt2[1]*perc))

            # compute the center of the contour
            M = cv2.moments(cnt)
            cX = int(M["m10"] / M["m00"])
            cY = int(M["m01"] / M["m00"])

            # draw the contour and center of the shape on the image
            cv2.drawContours(imgContour, [cnt], -1, (0, 255, 0), 2)
            radius = int(area - (area*0.6))
            cv2.circle(imgContour, (cX, cY), radius, (0, 0, 255), 2)

            cv2.rectangle(imgContour, pt1, pt2, (0,0,255), 2)

#----------- Leitura dos parametros
# ap = argparse.ArgumentParser()
# ap.add_argument("-i", "--image", required = True, help = "Path to the image")
# args = vars(ap.parse_args())
# colorPath = args["image"]

colorPath = './resources/amostras/algodao_in-natura_400x300.jpg'

# color_to_check_BGR = cv2.imread('./resources/color-samples/1x1_60-6-100.png')
# print(color_to_check_BGR)
# exit()

#----------- Cores pre-definidas
color_60_0_100_LAB = cv2.cvtColor(np.array([[[255, 255, 255]]]).astype(np.float32) / 255, cv2.COLOR_BGR2LAB)
color_60_2_100_LAB = cv2.cvtColor(np.array([[[249, 255, 255]]]).astype(np.float32) / 255, cv2.COLOR_BGR2LAB)
color_60_4_100_LAB = cv2.cvtColor(np.array([[[244, 255, 255]]]).astype(np.float32) / 255, cv2.COLOR_BGR2LAB)
color_60_6_100_LAB = cv2.cvtColor(np.array([[[239, 255, 255]]]).astype(np.float32) / 255, cv2.COLOR_BGR2LAB)
color_60_8_100_LAB = cv2.cvtColor(np.array([[[234, 255, 255]]]).astype(np.float32) / 255, cv2.COLOR_BGR2LAB)
color_60_10_100_LAB = cv2.cvtColor(np.array([[[229, 255, 255]]]).astype(np.float32) / 255, cv2.COLOR_BGR2LAB)
color_60_12_100_LAB = cv2.cvtColor(np.array([[[224, 255, 255]]]).astype(np.float32) / 255, cv2.COLOR_BGR2LAB)
color_60_20_100_LAB = cv2.cvtColor(np.array([[[204, 255, 255]]]).astype(np.float32) / 255, cv2.COLOR_BGR2LAB)
color_60_24_100_LAB = cv2.cvtColor(np.array([[[193, 255, 255]]]).astype(np.float32) / 255, cv2.COLOR_BGR2LAB)

colors = {
    "WB-60-0-100": color_60_0_100_LAB,
    "WB-60-2-100": color_60_2_100_LAB,
    "WB-60-4-100": color_60_4_100_LAB,
    "WB-60-6-100": color_60_6_100_LAB,
    "WB-60-8-100": color_60_8_100_LAB,
    "WB-60-10-100": color_60_10_100_LAB,
    "WB-60-12-100": color_60_12_100_LAB,
    "WB-60-20-100": color_60_20_100_LAB,
    "WB-60-24-100": color_60_24_100_LAB
}

#----------- leitura do arquivo imagem
image1_bgr = cv2.imread(colorPath)
image1_HSV = cv2.cvtColor(image1_bgr, cv2.COLOR_BGR2HSV)

colorFound = {
    "colorName": '',
    "delta": -1
}

#----------- máscara para remover o fundo preto
# cria os arrays para serem usados como limite na máscara
h_min, h_max, s_min, s_max, v_min, v_max = [0, 179, 0, 255, 78, 255]
lowerLimit = np.array([h_min,s_min,v_min])
upperLimit = np.array([h_max,s_max,v_max])
mask = cv2.inRange(image1_HSV, lowerLimit, upperLimit)

imgResult_BGR = cv2.bitwise_and(image1_bgr, image1_bgr, mask=mask)

imgResult_RGB = cv2.cvtColor(imgResult_BGR, cv2.COLOR_BGR2RGB)

imgContour = imgResult_RGB.copy()

imgBlur = cv2.GaussianBlur(imgResult_RGB, (7,7),1)
imgCanny = cv2.Canny(imgBlur, 50, 50) # pega os contornos da imagem
getContours(imgCanny)

cv2.imshow('contours', imgContour)
cv2.waitKey(0)

exit()

# cv2.imwrite('img_result.jpg', imgResult_BGR) 
# cv2.imshow('original',image1_bgr)
# cv2.imshow('mask',mask)
# cv2.imshow('imgLimpa', imgResult_BGR)
# cv2.waitKey(0)

image1_lab = cv2.cvtColor(imgResult_BGR.astype(np.float32) / 255, cv2.COLOR_BGR2LAB)
# image1_lab = cv2.cvtColor(mx.astype(np.float32) / 255, cv2.COLOR_BGR2LAB)

#----------- laço para procurar fazer o match por cor no array de cores pré-definidas
for key in colors:
    color = colors[key]
    delta_E_2000 = colour.delta_E(image1_lab, color, method='cie2000')
    delta = np.mean(delta_E_2000)

    if colorFound["delta"] == -1 or colorFound["delta"] > delta :
        colorFound["colorName"] = key
        colorFound["delta"] = delta


print('\n\nA imagem "{}" mais se assemelha da cor "{}" e o delta calculado foi de "{}"'.format(colorPath, colorFound["colorName"], colorFound["delta"]))

我很乐意提供任何帮助,谢谢。

EN

回答 1

Stack Overflow用户

发布于 2021-01-25 22:31:53

使用CIE Lab颜色空间的好处之一是可以使用两个颜色向量之间的欧几里德距离来计算色差。

如果您需要比较每个像素的颜色,那么就这样做,并计算每个非黑色像素的增量。另一种方法可能是计算非黑色像素的平均颜色,并使用该平均颜色计算增量。

它将有助于获得原始图像的样本,以及给定图像的预期输出是什么:它是与字典中的颜色之一匹配,还是在图像的特定区域中的本地匹配?

编辑:您可以简单地计算亮度不是零的像素的平均值,如下所示:

代码语言:javascript
复制
np.mean(img[img> 0])

对于实验室映像中的每一层,您都可以这样做:

代码语言:javascript
复制
mean_l = np.mean(lab[lab > 0][:, :, 0])
mean_a = np.mean(lab[lab > 0][:, :, 1])
mean_b = np.mean(lab[lab > 0][:, :, 2])
mean_color = np.array([mean_l, mean_a, mean_b])
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64850907

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档