百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

利用机器学习进行皮肤分割和主色调颜色提取

toyiye 2024-06-21 11:55 11 浏览 0 评论

今天我们将学习使用OpenCV来分割皮肤并使用Sci Kit学习执行K-Means聚类以找到主要的肤色。

假设您了解基本的python并了解OpenCV。我们将涵盖对K-Means和OpenCV的一些方法的高级理解。我们还将讨论不同的色彩空间。

本文的重点是解释代码背后的概念。

什么是OpenCV?

“OpenCV是一个主要针对实时计算机视觉的编程函数库”

那么什么是计算机视觉?

“计算机视觉涉及从单个图像或一系列图像中自动提取,分析和理解有用信息。它涉及开发理论和算法基础,以实现自动视觉理解。“

计算机视觉是人工智能的一个子领域,它涵盖了从简单的物体识别到生产级机器人的应用。一个示例用例,每个人都可以与Facebook建议在上传照片时标记自己或朋友。

因此,让我们使用高级解释,并为OpenCV做一个简单的定义

“OpenCV是一个计算机视觉库,可帮助我们使用图像处理技术从图像或视频中提取/分析数据”。

什么是Sci-Kit学习?

“Scikit-learn(以前称为scikits.learn)是一个用于Python编程语言的免费软件机器学习库。它具有各种分类,回归和聚类算法,包括支持向量机,随机森林,梯度增强,k-means和DBSCAN“

机器学习是人工智能的子领域,其重点是为计算机/系统提供自动从数据学习而无需明确编程的算法。它基本上意味着允许计算机在没有“if else”语句的情况下进行预测或假设。

机器学习算法包括

  • 监督学习
  • 无人监督的学习
  • 强化学习

什么是K-Means聚类?

K-Means聚类是一种无监督学习算法。聚类算法的基本原理是它在给定数据集中找到具有相似特征的数据点组。K-Means是一种这样的聚类算法,它将数据分组为“K”组/clusters。

这个过程很简单:

  1. 选择clusters 数量(K)
  2. 随机放置K个数据点(初始质心)
  3. 将数据集中的点分配给最近的质心(这通常是从质心中找到点的欧几里德距离)
  4. 通过获取每个cluster中的数据点的平均值来重新计算新的质心。
  5. 重复3和4直到质心不移动。


Python编码

实现的过程:

  • 1. 读取图像 - 这可以使用OpenCV完成
  • 2. 从图像中分割出皮肤 - 这也可以使用OpenCV完成
  • 3. 找到主导色彩 - 这是主要目标!我们将在Scikit-learn python包的帮助下使用K-Mean聚类算法。

所以我们分三个步骤。在您真正理解代码之前需要了解一些事项

1.OpenCV在“BGR Color Space”中读取彩色图像。

这与“RGB色彩空间”相反。

2.使用HSV颜色空间中的阈值处理完成皮肤分割

HSV(Hue, Saturation, Value)是用于表示与人类感知对齐的RGB颜色的模型。Hue表示特定颜色的波长优势,Saturation表示颜色的深浅,Value表示颜色的强度。

阈值处理是通过基于定义的阈值过滤掉像素来创建二值图像的过程。简单来说,取图像的每个像素,如果该像素在“阈值”范围内,如果不使其为黑色,则使其为白色。在我们的上下文中,阈值将是表示“肤色”范围的HSV值。SV的范围可以通过试错得到。

我们将使用cv2.inRange()方法进行阈值处理,并使用cv2.bitwise_and()从二进制图像中获取最终的减影图像。

还有一些其他要点可以了解要使用的库

OpenCV使用Numpy数组作为数据类型。

默认情况下,OpenCV无法处理透明图像。它将透明视为黑色

由于cv2.imshow()在Google Collab中不起作用,我们将使用matplotlib的plypot“imshow”方法来显示图像。

我们将使用PyImageSearch.com的Adrian Rosebrock作者提供的令人敬畏的“ imutils ”库。

Python代码如下:

import numpy as np
import cv2
from sklearn.cluster import KMeans
from collections import Counter
import imutils
import pprint
from matplotlib import pyplot as plt
 
 
def extractSkin(image):
 # Taking a copy of the image
 img = image.copy()
 # Converting from BGR Colours Space to HSV
 img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
 
 # Defining HSV Threadholds
 lower_threshold = np.array([0, 48, 80], dtype=np.uint8)
 upper_threshold = np.array([20, 255, 255], dtype=np.uint8)
 
 # Single Channel mask,denoting presence of colours in the about threshold
 skinMask = cv2.inRange(img, lower_threshold, upper_threshold)
 
 # Cleaning up mask using Gaussian Filter
 skinMask = cv2.GaussianBlur(skinMask, (3, 3), 0)
 
 # Extracting skin from the threshold mask
 skin = cv2.bitwise_and(img, img, mask=skinMask)
 
 # Return the Skin image
 return cv2.cvtColor(skin, cv2.COLOR_HSV2BGR)
 
 
def removeBlack(estimator_labels, estimator_cluster):
 
 # Check for black
 hasBlack = False
 
 # Get the total number of occurance for each color
 occurance_counter = Counter(estimator_labels)
 
 # Quick lambda function to compare to lists
 def compare(x, y): return Counter(x) == Counter(y)
 
 # Loop through the most common occuring color
 for x in occurance_counter.most_common(len(estimator_cluster)):
 
 # Quick List comprehension to convert each of RBG Numbers to int
 color = [int(i) for i in estimator_cluster[x[0]].tolist()]
 
 # Check if the color is [0,0,0] that if it is black
 if compare(color, [0, 0, 0]) == True:
 # delete the occurance
 del occurance_counter[x[0]]
 # remove the cluster
 hasBlack = True
 estimator_cluster = np.delete(estimator_cluster, x[0], 0)
 break
 
 return (occurance_counter, estimator_cluster, hasBlack)
 
 
def getColorInformation(estimator_labels, estimator_cluster, hasThresholding=False):
 
 # Variable to keep count of the occurance of each color predicted
 occurance_counter = None
 
 # Output list variable to return
 colorInformation = []
 
 # Check for Black
 hasBlack = False
 
 # If a mask has be applied, remove th black
 if hasThresholding == True:
 
 (occurance, cluster, black) = removeBlack(
 estimator_labels, estimator_cluster)
 occurance_counter = occurance
 estimator_cluster = cluster
 hasBlack = black
 
 else:
 occurance_counter = Counter(estimator_labels)
 
 # Get the total sum of all the predicted occurances
 totalOccurance = sum(occurance_counter.values())
 
 # Loop through all the predicted colors
 for x in occurance_counter.most_common(len(estimator_cluster)):
 
 index = (int(x[0]))
 
 # Quick fix for index out of bound when there is no threshold
 index = (index-1) if ((hasThresholding & hasBlack)
 & (int(index) != 0)) else index
 
 # Get the color number into a list
 color = estimator_cluster[index].tolist()
 
 # Get the percentage of each color
 color_percentage = (x[1]/totalOccurance)
 
 # make the dictionay of the information
 colorInfo = {"cluster_index": index, "color": color,
 "color_percentage": color_percentage}
 
 # Add the dictionary to the list
 colorInformation.append(colorInfo)
 
 return colorInformation
 
 
def extractDominantColor(image, number_of_colors=5, hasThresholding=False):
 
 # Quick Fix Increase cluster counter to neglect the black(Read Article)
 if hasThresholding == True:
 number_of_colors += 1
 
 # Taking Copy of the image
 img = image.copy()
 
 # Convert Image into RGB Colours Space
 img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 
 # Reshape Image
 img = img.reshape((img.shape[0]*img.shape[1]), 3)
 
 # Initiate KMeans Object
 estimator = KMeans(n_clusters=number_of_colors, random_state=0)
 
 # Fit the image
 estimator.fit(img)
 
 # Get Colour Information
 colorInformation = getColorInformation(
 estimator.labels_, estimator.cluster_centers_, hasThresholding)
 return colorInformation
 
 
def plotColorBar(colorInformation):
 # Create a 500x100 black image
 color_bar = np.zeros((100, 500, 3), dtype="uint8")
 
 top_x = 0
 for x in colorInformation:
 bottom_x = top_x + (x["color_percentage"] * color_bar.shape[1])
 
 color = tuple(map(int, (x['color'])))
 
 cv2.rectangle(color_bar, (int(top_x), 0),
 (int(bottom_x), color_bar.shape[0]), color, -1)
 top_x = bottom_x
 return color_bar
 
 
"""## Section Two.4.2 : Putting it All together: Pretty Print
 
The function makes print out the color information in a readable manner
"""
 
 
def prety_print_data(color_info):
 for x in color_info:
 print(pprint.pformat(x))
 print()
 
 
"""
The below lines of code, is the implementation of the above defined function.
"""
 
'''
Skin Image Primary : https://raw.githubusercontent.com/octalpixel/Skin-Extraction-from-Image-and-Finding-Dominant-Color/master/82764696-open-palm-hand-gesture-of-male-hand_image_from_123rf.com.jpg
Skin Image One : https://raw.githubusercontent.com/octalpixel/Skin-Extraction-from-Image-and-Finding-Dominant-Color/master/skin.jpg
Skin Image Two : https://raw.githubusercontent.com/octalpixel/Skin-Extraction-from-Image-and-Finding-Dominant-Color/master/skin_2.jpg
Skin Image Three : https://raw.githubusercontent.com/octalpixel/Skin-Extraction-from-Image-and-Finding-Dominant-Color/master/Human-Hands-Front-Back-Image-From-Wikipedia.jpg
 
'''
 
 
# Get Image from URL. If you want to upload an image file and use that comment the below code and replace with image=cv2.imread("FILE_NAME")
image = imutils.url_to_image(
 "https://raw.githubusercontent.com/octalpixel/Skin-Extraction-from-Image-and-Finding-Dominant-Color/master/82764696-open-palm-hand-gesture-of-male-hand_image_from_123rf.com.jpg")
 
# Resize image to a width of 250
image = imutils.resize(image, width=250)
 
# Show image
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.show()
 
# Apply Skin Mask
skin = extractSkin(image)
 
plt.imshow(cv2.cvtColor(skin, cv2.COLOR_BGR2RGB))
plt.show()
 
# Find the dominant color. Default is 1 , pass the parameter 'number_of_colors=N' where N is the specified number of colors
dominantColors = extractDominantColor(skin, hasThresholding=True)
 
# Show in the dominant color information
print("Color Information")
prety_print_data(dominantColors)
 
# Show in the dominant color as bar
print("Color Bar")
colour_bar = plotColorBar(dominantColors)
plt.axis("off")
plt.imshow(colour_bar)
plt.show()

这将是代码的最终输出,将颜色信息和颜色条如下所示。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码