整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

计算机视觉-python实现花的分类

计算机视觉-python实现花的分类

建一个rbghistogram.py文件

import cv2 
class RGBHistogram:
 def __init__(self,bins):
 # store the number of bins the histogram will use 
 self.bins=bins 
 def describe(self,image,mask=None):
 # compute a 3D histogram in the RGB colorspace,
 # then normalize the histogram so that images
 # with the same content,but either scaled larger
 # or smaller will have(roughly) the same histogram
 hist=cv2.calcHist([image],[0,1,2],
 mask,self.bins,[0,256,0,256,0,256])
 cv2.normalize(hist,hist)
 # return out 3D histogram as a flattened array
 return hist.flatten() 

我们首先导入cv2,这是我们需要创建图像描述符的唯一的package。

然后,我们定义了RGBHistogram类,用于封装花卉图像的量化方式。__init__方法只接受一个参数——一个包含3D直方图的bins的列表。

描述图像将由describe方法处理,该方法接收两个参数,一个将构建颜色直方图的图像,以及一个可选的mask。如果我们提供mask,则只有与mask区域相关联的像素将用于构造直方图。这允许我们仅描述图像的花瓣,忽略图像的其余部分(即,背景,其与花本身无关)。

接着,构造直方图。calcHist函数的第一个参数是我们想要描述的图像的列表,该函数具体的参数请参考前面的文章。然后将生成的图像进行标准化,并以特征向量返回。

注意:cv2.normalize函数在OpenCV 2.4.X和OpenCV 3.0之间略有不同。 在OpenCV 2.4.X中,cv2.normalize函数实际上会返回规范化的直方图。 但是,在OpenCV 3.0+中,cv2.normalize实际上对函数内的直方图进行了规范化,并更新了传入的第二个参数(即“输出”)。这是一个微妙但重要的区别,在使用这两个参数时要记住 OpenCV版本.

现在已经定义了图像描述符,我们可以创建代码来对给定花朵的物种进行分类:

from __future__ import print_function
from preprocess import RGBHistogram
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.cross_validation import train_test_split
from sklearn.metrics import classification_report
import numpy as np 
import argparse
import glob
import cv2 
# construct the argument parser and parse the arguments
ap=argparse.ArgumentParser()
ap.add_argument("-i", "--images", required=True,
 help="path to the image dataset")
ap.add_argument("-m", "--masks", required=True,
 help="path to the image masks")
args=vars(ap.parse_args())

我们首先导入必要的package。我们首先导入了RGBHistogram用于描述我们的每个图像。

然后导入scikit-learn库的LabelEncoder类。为了构建机器学习分类器以区分花种,我们首先需要一种方法来编码与每个花类相关联的“类标签”。我们希望将向日葵,番红花,雏菊和三色紫罗兰区分开来,但为了构建机器学习模型,这些种类(以字符串表示的)需要转换为整数。LabelEncoder类就是用来干这件事的。

我们使用的实际分类模型是RandomForestClassifier。随机森林是用于分类的集成学习方法,由多个决策树组成。

对于随机森林中的每棵树,构建一个自举(替换采样)样本,通常由66%的数据集组成。然后,基于自举样本构建决策树。在树中的每个节点处,仅采用预测变量的样本来计算节点分割标准。通常使用sqrt(n)预测变量,其中n是特征空间中预测变量的数量。然后重复该过程以训练森林中的多棵树(关于随机森林分类器的详细内容超出了本文的范围,有兴趣的可以参考机器学习方法)。

但是,如果您是使用机器学习的新手,随机森林是一个很好的起点,特别是在计算机视觉领域,他们只需很少的努力即可获得更高的精度。同样,虽然这不适用于所有计算机视觉分类问题,但随机森林是获得基线准确度的良好起点。

然后我们从scikit-learn导入train_test_split函数。在构建机器学习模型时,我们需要两组数据:训练集(training set)和测试(testing set)(或验证(validation set))集。

我们使用training data对机器学习模型进行训练(在这种情况下,我们使用随机森林学习模型)。然后使用testing data对模型进行评估。

保持这两组是独一无二的非常重要,因为它允许在尚未看到的数据点上评估模型。如果模型已经看到了数据点,那么结果是有偏见的,因为它具有不公平的优势!

最后,我们使用NumPy进行数值处理,使用argparse来解析命令行参数,使用glob来抓取磁盘上的图像路径,使用cv2进行OpenCV绑定。

接着我们需要两个命令行参数:--images,指向包含其花图像的目录,--mask,指向包含mask鲜花的目录。这些mask使我们只能专注于我们想要描述的花朵部分(即花瓣),忽略背景和其他杂乱,否则会扭曲特征向量并插入不需要的噪音。

更多关于此数据集请参考Flowers

# grab the image and mask paths 
imagePaths=sorted(glob.glob(args["images"] + "\\*.png"))
maskPaths=sorted(glob.glob(args["masks"] + "\\*.png"))
# initialize the list of data and class label targets
data=[]
target=[]
# initialize the image descriptor
desc=RGBHistogram([8,8,8])
# loop over the image and mask paths 
for (imagePath,maskPath) in zip(imagePaths,maskPaths):
 # load the image and mask 
 image=cv2.imread(imagePath)
 mask=cv2.imread(maskPath)
 mask=cv2.cvtColor(mask,cv2.COLOR_BGR2GRAY)
 # describe the image 
 features=desc.describe(image,mask)
 # update the list of data and targets 
 data.append(features)
 target.append(imagePath.split("_")[-2])

我们使用glob来分别抓住我们的图像和mask的路径。通过传入包含图像的目录,然后是通配符*.png,我们能够快速构建图像路径列表。

接着,我们简单地初始化数据矩阵和类标签列表(即花的种类)。

然后实例化我们的图像描述符——每个通道有8个bins的3D RGB颜色直方图。该图像描述符将产生用于表征花的颜色的8×8×8=512维特征向量。

接着我们开始在我们的图像和mask上循环。我们将图像和mask从磁盘中加载进来,然后在、将mask转换为灰度。

接着应用我们的3D RGB颜色直方图产生我们的特征向量,然后将其存储在数据矩阵中。

然后解析花的种类,并更新target列表。

现在我们可以应用我们的机器学习方法了。

# grab the unique target names and encode the labels 
targetNames=np.unique(target)
le=LabelEncoder()
target=le.fit_transform(target)
# construct the training and testing splits 
(trainData,testData,trainTarget,testTarget)=train_test_split(data,target,
 test_size=0.3,random_state=42)
# train the classifier
model=RandomForestClassifier(n_estimators=25,random_state=84)
model.fit(trainData,trainTarget)
# evaluate the classifier 
print(classification_report(testTarget,model.predict(testData),
 target_names=targetNames))

首先,我们给我们的类标签进行编码。NumPy的unique方法用于查找唯一的species名称,然后将其输入LabelEncoder。调用fit_transform将“唯一”物种名称“拟合(fits)”为整数,一个species对应于一个category,然后将字符串“转换(transform)”为相应的整数类。target变量现在包含一个整数列表,每个数据点对应一个整数列表,其中每个整数映射到一个花种名称。

接着,我们开始构建我们的训练和测试集。我们将使用train_test_split函数。我们需要传递我们数据矩阵和target列表,指定测试数据集是整个数据集大小的30%。使用伪随机状态42,以便我们可以在以后的运行中重现我们的结果。

调用RandomForestClassifier函数,使用森林中的25个决策树进行训练。同样,明确使用伪随机状态,以便我们的结果是可重复的。

然后使用classification_report函数打印出我们的模型的准确性。我们将实际testing targets作为第一个参数传递,然后让模型预测它认为花种对测试数据的影响。然后,classification_report函数将预测与真实targets进行比较,并为整个系统和每个单独的类别标签打印准确度报告。

为了进一步研究分类,我们定义了以下代码:

# loop over a sample of the images 
for i in np.random.choice(np.arange(0,len(imagePaths)),10):
 # grab the image and mask paths 
 imagePath=imagePaths[i]
 maskPath=maskPaths[i]
 # load the image and mask 
 image=cv2.imread(imagePath)
 mask=cv2.imread(maskPath)
 mask=cv2.cvtColor(mask,cv2.COLOR_BGR2GRAY)
 # describe the image 
 features=desc.describe(image,mask)
 # predict what type of flower the image is 
 flower=le.inverse_transform(model.predict([features]))[0]
 print(imagePath)
 print("I think this flower is a {}".format(flower.upper()))
 cv2.imshow("image",image)
 cv2.waitKey(0)

我们首先从所有图片里面随机挑选10张不同的图像进行调查,然后获取对应的图片和mask的路径。

然后我们将图片和mask的路径加载进来。并将mask图片转换为灰度图像。

然后,我们利用describe提取特征向量,以表征花的颜色。

我们查询我们的随机森林分类器以确定花的种类,然后将其打印到控制台并屏幕上显示。

最后执行我们的脚本程序:

python classify.py --image dataset\images --mask dataset\masks

运行结果

博客地址(有完整代码):https://0leo0.github.io/2018/case_study_06.html

关注不迷路哦!!!

TML 代码约定

很多 Web 开发人员对 HTML 的代码规范知之甚少。

在2000年至2010年,许多Web开发人员从 HTML 转换到 XHTML。

使用 XHTML 开发人员逐渐养成了比较好的 HTML 编写规范。

而针对于 HTML5 ,我们应该形成比较好的代码规范,以下提供了几种规范的建议。

使用正确的文档类型

文档类型声明位于HTML文档的第一行:

<!DOCTYPE html>

如果你想跟其他标签一样使用小写,可以使用以下代码:

<!doctype html>

使用小写元素名

HTML5 元素名可以使用大写和小写字母。

推荐使用小写字母:

  • 混合了大小写的风格是非常糟糕的。

  • 开发人员通常使用小写 (类似 XHTML)。

  • 小写风格看起来更加清爽。

  • 小写字母容易编写。

不推荐:

<SECTION>

<p>这是一个段落。</p>

</SECTION>

非常糟糕:

<Section>

<p>这是一个段落。</p>

</SECTION>

推荐:

<section>

<p>这是一个段落。</p>

</section>

关闭所有 HTML 元素

在 HTML5 中, 你不一定要关闭所有元素 (例如 <p> 元素),但我们建议每个元素都要添加关闭标签。

不推荐:

<section>

<p>这是一个段落。

<p>这是一个段落。

</section>

推荐:

<section>

<p>这是一个段落。</p>

<p>这是一个段落。</p>

</section>

关闭空的 HTML 元素

在 HTML5 中, 空的 HTML 元素也不一定要关闭:

我们可以这么写:

<meta charset="utf-8">

也可以这么写:

<meta charset="utf-8" />

在 XHTML 和 XML 中斜线 (/) 是必须的。

如果你期望 XML 软件使用你的页面,使用这种风格是非常好的。

使用小写属性名

HTML5 属性名允许使用大写和小写字母。

我们推荐使用小写字母属性名:

  • 同时使用大小写是非常不好的习惯。

  • 开发人员通常使用小写 (类似 XHTML)。

  • 小写风格看起来更加清爽。

  • 小写字母容易编写。

不推荐:

<div CLASS="menu">

推荐:

<div class="menu">

属性值

HTML5 属性值可以不用引号。

属性值我们推荐使用引号:

  • 如果属性值含有空格需要使用引号。

  • 混合风格不推荐的,建议统一风格。

  • 属性值使用引号易于阅读。

以下实例属性值包含空格,没有使用引号,所以不能起作用:

<table class=table striped>

以下使用了双引号,是正确的:

<table class="table striped">

图片属性

图片通常使用 alt 属性。 在图片不能显示时,它能替代图片显示。

<img src="html5.gif" alt="HTML5" style="width:128px;height:128px">

定义好图片的尺寸,在加载时可以预留指定空间,减少闪烁。

<img src="html5.gif" alt="HTML5" style="width:128px;height:128px">

空格和等号

等号前后可以使用空格。

<link rel="stylesheet" href="styles.css">

但我们推荐少用空格:

<link rel="stylesheet" href="styles.css">

避免一行代码过长

使用 HTML 编辑器,左右滚动代码是不方便的。

每行代码尽量少于 80 个字符。

空行和缩进

不要无缘无故添加空行。

为每个逻辑功能块添加空行,这样更易于阅读。

缩进使用两个空格,不建议使用 TAB。

比较短的代码间不要使用不必要的空行和缩进。

不必要的空行和缩进:

<body>

<h1>菜鸟教程</h1>

<h2>HTML</h2>

<p>

菜鸟教程,学的不仅是技术,更是梦想。

菜鸟教程,学的不仅是技术,更是梦想。

菜鸟教程,学的不仅是技术,更是梦想,

菜鸟教程,学的不仅是技术,更是梦想。

</p>

</body>

推荐:

<body>

<h1>菜鸟教程</h1>

<h2></h2>

<p>菜鸟教程,学的不仅是技术,更是梦想。

菜鸟教程,学的不仅是技术,更是梦想。

菜鸟教程,学的不仅是技术,更是梦想。

菜鸟教程,学的不仅是技术,更是梦想。</p>

</body>

表格实例:

<table>

<tr>

<th>Name</th>

<th>Description</th>

</tr>

<tr>

<td>A</td>

<td>Description of A</td>

</tr>

<tr>

<td>B</td>

<td>Description of B</td>

</tr>

</table>

列表实例:

<ol>

<li>London</li>

<li>Paris</li>

<li>Tokyo</li>

</ol>

省略 <html> 和 <body>?

在标准 HTML5 中, <html> 和 <body> 标签是可以省略的。

以下 HTML5 文档是正确的:

实例:

<!DOCTYPE html>

<head>

<title>页面标题</title>

</head>

<h1>这是一个标题</h1>

<p>这是一个段落。</p>

尝试一下 ?

不推荐省略 <html> 和 <body> 标签。

<html> 元素是文档的根元素,用于描述页面的语言:

<!DOCTYPE html>

<html lang="zh">

声明语言是为了方便屏幕阅读器及搜索引擎。

省略 <html> 或 <body> 在 DOM 和 XML 软件中会崩溃。

省略 <body> 在旧版浏览器 (IE9)会发生错误。

省略 <head>?

在标准 HTML5 中, <head>标签是可以省略的。

默认情况下,浏览器会将 <body> 之前的内容添加到一个默认的 <head> 元素上。

实例

<!DOCTYPE html>

<html>

<title>页面标题</title>

<body>

<h1>这是一个标题</h1>

<p>这是一个段落。</p>

</body>

</html>

尝试一下 ?

现在省略 head 标签还不推荐使用。

元数据

HTML5 中 <title> 元素是必须的,标题名描述了页面的主题:

<title>菜鸟教程</title>

标题和语言可以让搜索引擎很快了解你页面的主题:

<!DOCTYPE html>

<html lang="zh">

<head>

<meta charset="UTF-8">

<title>菜鸟教程</title>

</head>

HTML 注释

注释可以写在 <!-- 和 --> 中:

<!-- 这是注释 -->

比较长的评论可以在 <!-- 和 --> 中分行写:

<!--

这是一个较长评论。 这是 一个较长评论。这是一个较长评论。

这是 一个较长评论 这是一个较长评论。 这是 一个较长评论。

-->

长评论第一个字符缩进两个空格,更易于阅读。

样式表

样式表使用简洁的语法格式 ( type 属性不是必须的):

<link rel="stylesheet" href="styles.css">

短的规则可以写成一行:

p.into {font-family: Verdana; font-size: 16em;}

长的规则可以写成多行:

body {

background-color: lightgrey;

font-family: "Arial Black", Helvetica, sans-serif;

font-size: 16em;

color: black;

}

  • 将左花括号与选择器放在同一行。

  • 左花括号与选择器间添加以空格。

  • 使用两个空格来缩进。

  • 冒号与属性值之间添加已空格。

  • 逗号和符号之后使用一个空格。

  • 每个属性与值结尾都要使用符号。

  • 只有属性值包含空格时才使用引号。

  • 右花括号放在新的一行。

  • 每行最多 80 个字符。

在逗号和分号后添加空格是常用的一个规则。

在 HTML 中载入 JavaScript

使用简洁的语法来载入外部的脚本文件 ( type 属性不是必须的 ):

<script src="myscript.js">

使用 JavaScript 访问 HTML 元素

一个糟糕的 HTML 格式可能会导致 JavaScript 执行错误。

以下两个 JavaScript 语句会输出不同结果:

实例

var obj=getElementById("Demo")

var obj=getElementById("demo")

HTML 中 JavaScript 尽量使用相同的命名规则。

访问 JavaScript 代码规范。

使用小写文件名

大多 Web 服务器 (Apache, Unix) 对大小写敏感: london.jpg 不能通过 London.jpg 访问。

其他 Web 服务器 (Microsoft, IIS) 对大小写不敏感: london.jpg 可以通过 London.jpg 或 london.jpg 访问。

你必须保持统一的风格,我们建议统一使用小写的文件名。

文件扩展名

HTML 文件后缀可以是 .html (或r .htm)。

CSS 文件后缀是 .css

JavaScript 文件后缀是 .js

.htm 和 .html 的区别

.htm 和 .html 的扩展名文件本质上是没有区别的。浏览器和 Web 服务器都会把它们当作 HTML 文件来处理。

区别在于:

.htm 应用在早期 DOS 系统,系统现在或者只能有三个字符。

在 Unix 系统中后缀没有特别限制,一般用 .html。

技术上区别

如果一个 URL 没有指定文件名 (如 http://www.runoob.com/css/), 服务器会返回默认的文件名。通常默认文件名为 index.html, index.htm, default.html, 和 default.htm。

如果服务器只配置了 "index.html" 作为默认文件,你必须将文件命名为 "index.html", 而不是 "index.htm"。

但是,通常服务器可以设置多个默认文件,你可以根据需要设置默认文件吗。

不管怎样,HTML 完整的后缀是 ".html"。

如您还有不明白的可以在下面与我留言或是与我探讨QQ群308855039,我们一起飞!

天小编逛论坛,看到了一位神级大佬的作品,竟然用了8000CSS代码花了一幅蒙娜丽莎,简直惊为天人!小编我不得不把这源码COPY一份下来,分享给头条上的小伙伴们看看,或许是用了什么工具吧,小编我也不是很懂,但是如果是用CSS写的,那么这个人就真的是个大神了,好了话不多说,直接上效果图和代码!

这个蒙娜丽莎特效的源码文末有领取地址

CSS全部源码共享:

这个是照片版的蒙娜丽莎,大家能够看出差别有多大吗?

我的web前端技术学习交流群:733581373

我是一名前端开发程序员,自己整理了一份2018最全面前端学习资料,从最基础的HTML+CSS+JS到移动端HTML5到各种框架都有整理,送给每一位前端小伙伴,这里是小白聚集地,欢迎初学和进阶中的小伙伴。

【这个蒙娜丽莎特效的源码也上传qun文件了的】

最后再给初学前端的小伙伴说几句:

HTML相当于告诉你网页上的东西是什么,例如:这是一个链接、这是一个标题、这是一个段落。HTML是构成网页的基础。

CSS相当于告诉你网页上的东西是什么样的,例如:这个链接是红色的、这个标题是蓝色的、这个段落是黑色的。CSS是作用在HTML元素之上的,可以调整HTML元素的样式,使网页布局更漂亮、合理。

JS相当于告诉你网页上的东西该怎么变化,例如:鼠标移动到链接上时链接变成蓝色、鼠标移动到头像上时显示个人信息等等。JS是在HTML和CSS的基础上的,作用是使网页使用起来更容易、方便。

ajax是前端需要用到的一个重要的技术。

Jquery是一个前端框架,主要作用是使编写JS代码更方便。