首页 > 云开发 > Python > 正文

后台-系统设置-扩展变量-手机广告位-内容正文顶部

使用python通过基于颜色的图像分割进行目标检测

Python
使用python通过基于颜色的图像分割进行目标检测
照片来自Pexels的rawpixel.com
入门
如果您已经安装了jupyter notebook或IDE,您可以运行python和OpenCV,只需跳到执行即可。

工具
我们今天的英雄是Anaconda。一个免费的开源发行版,有助于安装不同的软件包,并将它们的混乱分类到孤立的环境中。

维基百科告诉我们

Anaconda是用于科学计算(数据科学,机器学习应用程序,大规模数据处理,预测分析等)的Python和R编程语言的免费开源发行版,旨在简化包管理和部署。包版本由包管理系统conda管理。Anaconda发行版已被超过1200万用户使用,包括1400多种适用于Windows,Linux和MacOS的流行数据科学包。
以下是有关如何下载Anaconda的详细教程。
蟒蛇的Windows和蟒蛇的Linux版本。

创建环境
打开bash(cmd)并输入

$ conda create -n myEnv python = 3

提示下载软件包时键入y(表示是)。

$ source activate myEnv
$ conda install anaconda
$ conda activate myEnv
$ conda install opencv
$ jupyter notebook

这将在浏览器中为您打开jupyter notebook。

一些重要的术语
等高线
轮廓可以简单地解释为连接所有连续点(连同边界)的曲线,具有相同的颜色或强度。轮廓是形状分析和物体检测和识别的有用工具。

阈值
在灰度图像上应用阈值处理使其成为二值图像。您可以设置一个阈值,其中低于此阈值的所有值都将变为黑色,并且上述所有值都将变为白色。

执行
现在你已经拥有了所有你需要的东西。
我们将从一个简单的例子开始,向您展示基于颜色的分割是如何工作的。

跟我一起忍受,直到我们得到好东西。

一个Ombre圈 - 使用photoshop制作的图像

如果你想和我一起试试这个,你可以从这里免费获得这个图像。
在下面的代码中,我将把这个图像分成17个灰度级。然后使用轮廓测量每个级别的区域。

import cv2
import numpy as np
def viewImage(image):
    cv2.namedWindow('Display', cv2.WINDOW_NORMAL)
    cv2.imshow('Display', image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
def grayscale_17_levels (image):
    high = 255
    while(1): 
        low = high - 15
        col_to_be_changed_low = np.array([low])
        col_to_be_changed_high = np.array([high])
        curr_mask = cv2.inRange(gray, col_to_be_changed_low,col_to_be_changed_high)
        gray[curr_mask > 0] = (high)
        high -= 15
        if(low == 0 ):
            break
image = cv2.imread('./path/to/image')
viewImage(image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
grayscale_17_levels(gray)
viewImage(gray)

相同的图像分为17个灰度级

def get_area_of_each_gray_level(im):
## convert image to gray scale (must br done before contouring)
    image = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    output = []
    high = 255
    first = True
    while(1):
low = high - 15
        if(first == False):
# making values that are of a greater gray level black
            ## so it won't get detected 
            to_be_black_again_low = np.array([high])
            to_be_black_again_high = np.array([255])
            curr_mask = cv2.inRange(image, to_be_black_again_low,
            to_be_black_again_high)
            image[curr_mask > 0] = (0)
           
        # making values of this gray level white so we can calculate
        # it's area
        ret, threshold = cv2.threshold(image, low, 255, 0)
        contours, hirerchy = cv2.findContours(threshold,
        cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
if(len(contours) > 0):
output.append([cv2.contourArea(contours[0])])
            cv2.drawContours(im, contours, -1, (0,0,255), 3)
high -= 15
        first = False
        if(low == 0 ):
break
return output

在这个函数中,我只是通过将位于此范围内的所有数据统一到一个强度,在此迭代中简单地转换我想要轮廓(高亮)的灰色范围(强度)。我将所有其他强度转换为黑色(包括更大和更小的强度)。
第二步我对图像进行阈值处理,以便只有我想要轮廓的颜色现在显示为白色而其他所有颜色都转换为黑色。此步骤在这里没有太大变化,但必须完成,因为轮廓最适合黑白(阈值)图像。
在应用此步骤(阈值处理)之前,下面的图像将是相同的,除了白色环将是灰色的(第10个灰度级的灰度强度(255-15 * 10))

第10个部分单独出现以便能够计算其面积

image = cv2.imread('./ path / to / image')
print(get_area_of_each_gray_level(image))
viewImage(image)


17个灰度级的轮廓到原始图像上

包含区域值的数组

这样我们就可以得到每个灰度级的面积。

这真的很重要吗?
在我们继续之前,我想强调这个主题的重要性。
我是一名计算机工程专业的学生,我正在开展一个名为机器学习的项目,用于智能肿瘤检测和识别。
在该项目中使用基于颜色的图像分割来帮助计算机学习如何检测肿瘤。当处理MRI扫描时,程序必须检测所述MRI扫描的癌症水平。它通过将扫描分割成不同的灰度级别来实现这一点,其中最暗的是充满癌细胞,而最接近白色的是更健康的部分。然后它计算肿瘤对每个灰度级的隶属程度。有了这些信息,该程序能够识别肿瘤及其阶段。
该项目基于软计算,模糊逻辑和机器学习,您可以在模糊逻辑及其如何治愈癌症方面了解更多信息。

目标检测

照片来自  Pexels的Lukas

您可以得到这个图片上免费Pexels 这里。你只需要裁剪它。

在此图像中,我们只想轮廓化叶子。由于该图像的纹理非常不规则且不均匀,这意味着虽然没有很多颜色。该图像中的绿色强度也改变其亮度。因此,这里最好的做法是将所有这些不同的绿色阴影统一为一个阴影。这样当我们应用轮廓时,它将处理叶子作为一个整体对象。

注意:如果您在图像上应用轮廓线而不进行任何预处理,则会出现这种情况。我只是想让你看看叶子的不均匀性如何让OpenCV不明白这只是一个对象。

在没有预处理的情况下进行轮廓加工,检测到531个轮廓

import cv2
import numpy as np
def viewImage(image):
    cv2.namedWindow('Display', cv2.WINDOW_NORMAL)
    cv2.imshow('Display', image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

首先,您必须知道颜色的HSV表示,您可以通过将其RGB转换为HSV来了解它,如下所示。

## getting green HSV color representation
green = np.uint8([[[0, 255, 0 ]]])
green_hsv = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
print( green_hsv)

image = cv2.imread('./path/to/image.jpg')
hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
viewImage(hsv_img) ## 1
green_low = np.array([45 , 100, 50] )
green_high = np.array([75, 255, 255])
curr_mask = cv2.inRange(hsv_img, green_low, green_high)
hsv_img[curr_mask > 0] = ([75,255,200])
viewImage(hsv_img) ## 2
## converting the HSV image to Gray inorder to be able to apply
## contouring
RGB_again = cv2.cvtColor(hsv_img, cv2.COLOR_HSV2RGB)
gray = cv2.cvtColor(RGB_again, cv2.COLOR_RGB2GRAY)
viewImage(gray) ## 3
ret, threshold = cv2.threshold(gray, 90, 255, 0)
viewImage(threshold) ## 4
contours, hierarchy =  cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(image, contours, -1, (0, 0, 255), 3)
viewImage(image) ## 5

左图:转换为HSV后的图像(1)。右:应用蒙版后的图像(颜色统一)(2)

左:从HSV转换为灰色后的图像(3),右:阈值图像,最后一步(4)

最终轮廓(5)

由于背景中似乎也存在不规则性,我们可以使用这种方法获得最大的轮廓,最大的轮廓当然是叶子。
我们可以得到轮廓数组中叶子轮廓的索引,从中得到叶子的面积和中心。
轮廓具有许多其他可以使用的功能,例如轮廓周长,凸包,边界矩形等等。您可以从这里了解更多相关信息。

def findGreatesContour(contours):
    largest_area = 0
    largest_contour_index = -1
    i = 0
    total_contours = len(contours)
    while (i < total_contours ):
        area = cv2.contourArea(contours[i])
        if(area > largest_area):
            largest_area = area
            largest_contour_index = i
        i+=1
           
    return largest_area, largest_contour_index
# to get the center of the contour
cnt = contours[13]
M = cv2.moments(cnt)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
largest_area, largest_contour_index = findGreatesContour(contours)
print(largest_area)
print(largest_contour_index)
print(len(contours))
print(cX)
print(cY)

打印语句的结果

文章来源:medium,作者:。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:william.shi#ucloud.cn(邮箱中#请改为@)进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
后台-系统设置-扩展变量-手机广告位-内容正文底部

推荐文章

热门标签

    热门文章 最新文章 文章云

站内导航

全站搜索