【Lecture 5.3】Opencv 面部识别

2023-05-16

文章目录

    • Comparing Image Data Structures
    • OpenCV

Comparing Image Data Structures

OpenCV支持读取大多数文件格式的图像,例如JPEG,PNG和TIFF。 大多数图像和视频分析需要先将图像转换为grayscale 图。 这样可以简化图像并减少噪声,从而改善分析效果。 让我们编写一些代码,读取人像Floyd Mayweather 的图像并将其转换为灰度图。

# 首先我们导入cv2包 并加载图片
import cv2 as cv
img = cv.imread('readonly/floyd.jpg')
# 使用cv.cvtColor 方法将图片转换成 grayscale
gray = cv.cvtColor(img, cv.COLOR_BGR2GRY)

在我们查看图片处理结果之前,我们看一下 opencv 的文档,和 tesseract 一样,opencv也是用c++写的包,因此文档的内容也很少。但幸运的是网页版文档很全面,因此可以 在 docs.opencv.org 网站上学习特殊的函数用法。这里 函数 cvtColor 将图片从一个色彩空间转换成两一个色彩空间,这里我们把图片转换成灰度图。

we already know at least two different ways of doing this, using binarization and PIL color spaces conversions

# 让我们 inspect 返回的灰度图对象
import inspect
inspect.getmro(type(gray))

返回的:

(numpy.ndarray, object)

我们可以看到返回的图像的类型是:ndarray , 这与前面都不一样,前面我们处理的图片的类型都是 PIL.Image object 对象。但是 OpenCV 把一张图表示成二维比特序列(a two dimensional sequence of bytes),即 ndarray 所定义的类型。

# Lets look at the array contents.
gray
array([[ 40,  39,  39, ...,  77,  76,  75],
       [ 43,  42,  42, ...,  76,  75,  75],
       [ 39,  39,  39, ...,  76,  75,  74],
       ...,
       [ 21,  22,  24, ..., 219, 223, 209],
       [ 18,  20,  22, ..., 196, 206, 196],
       [ 16,  18,  20, ..., 168, 182, 176]], dtype=uint8)

对于这种类型的图片,并不能使用display的方法进行展示,我们还是使用PIL包对图像进行类型的转换a PIL object(take an array of data with a given color format and convert this into a PIL object),再 display

from PIL import Image
image = Image.fromarray(gray, 'L') # "L" is just an array of luminance values in unsigned integers
display(image)

扩展内容:关于opencv中的图片类型:多维数组。因此,array也可以定义为1维的。

import numpy as np
single_dim = np.array([25, 50, 25, 10, 10])

在图像中,这类似于在一个 grayscale 的每一行中的5个像素。 但是实际上,所有image库都倾向于至少包含两个维度,即a width and a height,,用一个矩阵表示。 因此,如果将single_dim放置在另一个数组中,则它将是一个二维数组,其中元素在高度方向上,而元素在高度方向上为5

# So if we put the single_dim inside of another array, this would be a two dimensional array with element in the height direction, and five in the width direction
double_dim = np.array([single_dim])
# 执行
double_dim
# -- 输出:二维数组
array([[25, 50, 25, 10, 10]])

不太理解:这个array第一维度有1个元素,这个元素包含一行5个值;

这看起来应该很熟悉,很像一个列表列表! 让我们看看如果显示新的二维数组是什么样子

display(Image.fromarray(double_dim,"L")) # display 一个数组图
# 输出
-  # 注实际:输出是一个图片

确切地说,实际上是连续的五个具有不同灰度的像素。 numpy库有一个很好的属性,称为shape,它使我们能够查看数组的维数。 shape属性返回一个元组 (height,width)

double_dim.shape
#-- 输出
(1, 5)

于是我们可以查看一下刚才的图片的数组维度:

img.shape
# --输出
(416, 416, 3)

可以看到这个图片有3个维度(height,width,color depth)在这种情况下,像素的颜色表示为三个值的数组。 让我们看一下第一个像素的颜色

first_pixel = img[0][0]  # 坐标(0,0)的元素的值
first_pixel

# -- 输出
array([33,35,53], dtype=uint8)

在这里,我们看到使用整数以RGB模式提供颜色值。 这意味着每种颜色通道都可以具有256个值之一,并且此数据可以表示的唯一颜色总数为256 * 256 * 256,大约为1600万种颜色。 我们将其称为24位颜色,即8 + 8 + 8。 如果您发现自己在买电视,可能会注意到一些昂贵的型号广告上标有10位甚至12位面板。 在这些电视中,红色,绿色和蓝色频道中的每个频道都由10或12位而不是8位表示。对于十位面板,这意味着有10亿种色彩,而12位面板的能力超过680亿 颜色!

对于数组的类型的数据还有一些别的常见操作,比如 reshape – change the number of rows and columns that are represented

print("Original image")
print(gray)

如果我们想把它重新表示为 one dimensional image 我们可以简单的使用 reshape方法

print("New image")
# reshape的参数
image1d = np.reshape(1, gray.shape[0]*gray.shape[1])
print(image1d)
# -- 输出
Original image
[[ 40  39  39 ...  77  76  75]
 [ 43  42  42 ...  76  75  75]
 [ 39  39  39 ...  76  75  74]
 ...
 [ 21  22  24 ... 219 223 209]
 [ 18  20  22 ... 196 206 196]
 [ 16  18  20 ... 168 182 176]]
New image
[[ 40  39  39 ... 168 182 176]]

因此,为什么我们要讨论这些嵌套的字节数组(nested arrays of bytes),我们本应该将OpenCV库。

还记得在上一堂课中我们想要查找图像中的 gaps 以便绘制线条以输入到 kranken吗? 我们使用了 PIL 模块,使用 getpixel() 查看单个像素并查看 luminosity,然后使用 ImageDraw.rectangle 实际填充黑条分隔符。 这是一个很好的高级API,让我们编写例程即可完成所需的工作,而不必过多地了解图像的存储方式。 但这在计算上非常慢。

但我们同样可以通过操作数组的值来完成它:

import cv2 as cv
img = cv.imread('readonly/two_col.png')
# 转换成灰度图
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

回忆列表切片的工作原理,如果您有一个数字列表,例如 a = [0,1,2,3,4,5],则 a[2:4] 将返回位置 at position 2 through 4 - 不要忘记列表从0开始索引!

如果我们有一个二维数组,则可以使用 a[2:4, 1:3] 格式将其切成较小的一部分。 您可以将其想象为先沿行维切片,然后沿列维切片。 因此,在此示例中,它将是第2行和第3行以及第1列和第2列的矩阵。这是我们的图像。

gray[2:4, 1:3]
# 输出
array([[255, 255],
       [255, 255]], dtype=uint8)

因此,我们看到它这个区域全是白色的。 我们可以将其用作“窗口”,并围绕我们的大图片进行移动。

最后,ndarray 库具有许多矩阵函数,这些函数通常运行速度非常快。 在这种情况下,我们要考虑的一个是count_nonzer(),它仅返回矩阵中不为零的条目数。

np.count_nonzero(gray[2:4, 1:3])
# 输出
4

好的,采用这种低级方法处理图像的最后一个好处是,我们也可以非常快速地更改像素。 前面我们使用的方法是绘制矩形并设置填充和线宽。 如果您要执行以下操作(例如,更改线条的填充颜色或绘制复杂形状),这将非常好。 但是我们真的只想在这里打线。 这真的很容易-我们只想将亮度值从255更改为0。

举个例子,我们创建一个 白色 矩阵

white_matrix = np.full((12,12), 255, dtype=np.uint8) #numpy创建数组
display(Image.fromarray(white_matrix, "L"))
white_matrix  # 忽略黑色部分截图残留

image-20200608234036958

array([[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]],
   dtype=uint8)

我们可以简单的把这个白色方块中的一列变成黑色

white_matrix[:, 6] = np.full((1,12), 0, dtype=np.uint8)

display(Image.fromarray(white_matrix, "L"))
white_matrix 

image-20200608234057152

array([[255, 255, 255, 255, 255, 255,   0, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255,   0, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255,   0, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255,   0, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255,   0, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255,   0, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255,   0, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255,   0, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255,   0, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255,   0, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255,   0, 255, 255, 255, 255, 255],
    [255, 255, 255, 255, 255, 255,   0, 255, 255, 255, 255, 255]],
   dtype=uint8)

这正是我们想要做的。 那么,当它看起来低得多时,为什么要用这种方式呢? 真的,答案就是速度。 使用矩阵存储和处理图像数据字节的这种方式与低级API和硬件开发人员如何考虑将文件和字节存储在内存中的方式非常接近。

它快多少? 好吧,这取决于您发现; 本周有一项可选任务,将我们的旧代码转换为这种新格式,以比较两种不同方法的可读性和速度。

OpenCV

好的,我们马上要做本课程的项目。如果您整体上对本系列课程进行反思,是一开始对Python 可能根本不了解,在数字教科书的帮助下逐步学习了python包含的基本控制结构和库,使用对象(object)对数据和函数的表示,现在开始探索存在于python的第三方库,该库允许您操纵和显示图像。这是一个很大的成就!

但是,您一直坚持不懈(persisted),在我们进入项目之前,我想与您分享另外一组 feature。 OpenCV 库包含对图像进行人脸检测(face detection on images)的机制。使用的技术基于Haar级联(Haar cascades),这是一种机器学习方法。现在,我们将不涉及机器学习的知识,我们还专门研究了使用Python的应用数据科学,如果您对该主题感兴趣的话,可以在此基础上进行学习。但是在这里,我们将OpenCV视为black box。

OpenCV附带(come with)了已经训练好的模型,用于检测面部,眼睛和微笑。

你也可以训练模型来检测其他事物(例如热狗或长笛flutes),如果对此感兴趣,我建议您查看有关如何训练级联分类器的Open CV文档:https://docs.opencv.org/3.4/dc/d88/tutorial_traincascade.html,但是,在本讲座中,我们只想使用当前的分类器,看看是否可以检测到图像中我们感兴趣的部分。

代码如下:

import cv2 as cv
# 读入已经训练好的模型
face_cascade = cv.CascadeClassifier('readonly/haarcascade_frontalface_default.xml')
eye_cascade = cv.CascadeClassifier('readonly/haarcascade_eye.xml')

# 检测face
# 读入图片 - 转换成灰度图
img = cv.imread('readonly/floyd.jpg')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 使用 face_cascade classifier, 可以查看文档,但一般使用 detectMultiScale() 函数
# 此函数以矩形形式返回对象列表。 第一个参数是图像的ndarray。
faces = face_cascade.detectMultiScale(gray)
# And lets just print those faces out to the screen
faces

输出:

array([[158,  75, 176, 176]], dtype=int32)

这个函数?

face.tolist()[0]
[158, 75, 176, 176]

产生的矩形框的格式是(x,y,w,h) ,其中 x 和 y 代表的是左上角点的坐标,w和h代表bounding box 的宽和高。

有了这个参数之后,我们可以使用前面我们在PIL库中的方法

from PIL import Image
# 创建一个图片的 PIL 对象
pil_img = Image.fromarray(gray,mode='L')
# 创建绘制对象
from PIL import ImageDraw
drawing = ImageDraw.Draw(pil_img)
# 尺寸参数
rec = faces.tolist()[0]
drawing.rectangle(rec, outline='white')
# 显示效果
display(pil_img)
image-20200612092943902

显然这个结果不是我们想要的,哪里出错了呢?

Well, a quick double check of the docs and it is apparent that OpenCV is return the coordinatesas (x,y,w,h), while PIL.ImageDraw is looking for (x1,y1,x2,y2).

我们重新写一下代码:

pil_img=Image.fromarray(gray,mode="L")
# Setup our drawing context
drawing=ImageDraw.Draw(pil_img)
# And draw the new box
drawing.rectangle((rec[0],rec[1],rec[0]+rec[2],rec[1]+rec[3]), outline="white")
# And display
display(pil_img)
image-20200612093222441

可以看到检测结果相当不错,请注意,这显然不是头部检测,但是我们使用的haarcascades文件寻找的是眼睛和嘴巴。 让我们尝试一些更复杂的事情,让我们读取一个动态图试试

img = cv.imread('readonly/msi_recruitment.gif')
display(Image.fromarray(img))

输出:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-36-a6d9e3885cc1> in <module>
      4 img = cv.imread('readonly/msi_recruitment.gif')
      5 # And lets take a look at that image
----> 6 display(Image.fromarray(img))

/opt/conda/lib/python3.7/site-packages/PIL/Image.py in fromarray(obj, mode)
   2506     .. versionadded:: 1.1.6
   2507     """
-> 2508     arr = obj.__array_interface__
   2509     shape = arr['shape']
   2510     ndim = len(shape)

AttributeError: 'NoneType' object has no attribute '__array_interface__'

事实证明,此错误的根源是OpenCV无法处理 Gif 图像。 这是一种痛苦和不幸。 但是我们知道如何解决这个问题? 一个是我们可以在PIL中打开它,然后将其另存为png,然后在open cv中打开它。

# 让我们使用 PIL 打开gif图片
pil_img = Image.open('readonly/msi_recruitment.gif')

# 现在opencv可以处理这个 PIL 对象格式的图片了
# 转化成灰度图像并保存
open_cv_version = pil_img.convert('L')
open_cv_version.save('msi_recruitment.png')

现在图像已经处理为 opencv 可以读取的png文件,我们来尝试检测这个图里的人脸:

cv_img = cv.imread('msi_recruitment.png')
# 不需要转灰度图,已经是灰度图了
# 注意这幅图里不止一个人脸
faces = face_cascade.detectMultiScale(cv_img)
# 我们使用PIL绘制face的坐标
pil_img = Image.open('readonly/msi_recruitment.gif')
drawing = ImageDraw.Draw(pil_img)
for x,y,w,h in faces:
    '''这可能是您的新语法! 回想一下,faces是(x,y,w,h)格式的矩形列表,即列表列表。 不必进行迭代然后手动提取每个项目,我们可以使用元组拆包将子列表中的单个项目直接提取到变量中。 一个非常好的python feature'''
    drawing.rectangle((x,y,x+w,y+h), outline='white')

display(pil_img)
image-20200612101214765

这里发生了什么!? 我们看到已经检测到脸部,并且在图像上的那些脸部周围绘制了框,但是颜色变得很奇怪了! 事实上,这与gif格式的图像的颜色限制有关。 简而言之,gif图像的颜色数量非常有限。a gif image:在调色板艺术家(pallette artists)用来混合颜料之后,这称为调色板(a color pallette)。For gifs the pallette can only be 256 colors-但它们可以是 any 256色。 引入新颜色时,必须占用旧颜色的空间。 在这种情况下,PIL将白色添加(绘制)到调色板(gif图像中)中,但不知道要替换哪种颜色,从而使图像混乱。

谁知道有太多关于图像格式的知识? 我们可以使用.mode属性查看图像处于哪种模式?

pil_img.mode
# 经过绘制的PIL图片的格式输出-----
'p'

在PIL库的文档中我们能法线很多的图片的mode,他们对应于不同的颜色空间,在这里我们把这个图片的mode转换到RGB色彩空间试试

pil_img = Image.open('readonly/msi_recruiment.gif')
pil_img = pil_image.covert('RGB')
pil_img.mode
'RGB'

好了,现在我们再尝试绘制正方形(faces)

drawing = ImageDraw(pil_img)
for x,y,w,h in faces:
    drawing.rectangle((x,y,x+w,y+h), outline='white')
    
display(pil_img)
image-20200612102637246

太棒了! 我们设法在该图像中检测出一堆人脸。 好像我们错过了四张脸。 在机器学习世界中,我们将这些称为假阴性:false negatives – 机器认为不是面孔(so a negative)的东西,但是在上面是不正确的。 因此,我们将检测到的真实面孔称为真阳性(true positives)-- 机器认为是正确的面孔。

此外还有误报(假阳性:false positives)-机器认为这是一张面孔,但事实上不是。 我们在图像中看到其中两个假阳性的结果,拾取衬衫中的阴影图案或纹理,并将其与 haarcascades匹配。

最后,我们有真阴性(true negatives),或者机器学习分类器可以考虑的所有可能矩形的集合,它正确地表明结果不是人脸。

我们还是可以尝试提高这个检测结果,要为给定图像找到良好的价值,需要进行大量的实验。 首先,让我们创建一个函数,该函数将在图像上为我们绘制矩形

# 创建在图片上画矩形的函数
def show_rects(faces):
    # 读取图片-创建绘制对象-绘制矩形(参数)
    pil_img = Image.open('readonly/msi_recruitment.gif').convert('RGB')
    drawing = ImageDraw.Draw(pil_img)
    for x,y,w,h in faces:    # 输入 faces 的坐标
        drawing.rectangle((x,y,x+w,y+h), outline='white')
    display(pil_img)

首先,我们可以尝试对图片做二值化(binarize)处理。 opencv库内置有二值化函数 threshold(). 根据函数的文档,是要输入参数:

  • the image,

  • the midpoint, and

  • the maximum value

  • a flag which indicates whether the threshold should bebinary or something else.

cv_img_bin = cv.threshold(img, 120, 255, cv.THRESH_BINARY)[1] # 将返回一个list,我们需要第二个值
# 为什么要第二个值?
# 对这张图片进行面部识别,获取面部坐标list
faces = face_cascade.detectMultiScale(cv_img_bin) 
# 在原图上绘制得到的face坐标的方框
show_rects(faces)
image-20200612151031548

这个运行结果图好像有问题?

很有意思。 不,但是我们确实看到底部有一个误报,分类器在其中检测到太阳镜是眼睛,下面是深色阴影线是嘴。
如果您在笔记本中观看此视频,为什么不暂停一下并尝试一些不同的阈值参数?

直接调整 xml模型参数

OpenCV的detectMultiScale()函数还具有几个参数。 首先是比例因子(scale factor)。 比例因子更改了针对模型(即haarcascades XML文件)考虑的矩形的大小。 您可以认为它好像在改变屏幕上矩形的大小。

# Lets experiment with the scale factor. Usually it's a small value, lets try 1.05
faces = face_cascade.detectMultiScale(cv_img,1.05)
# Show those results
show_rects(faces)
# Now lets also try 1.15
faces = face_cascade.detectMultiScale(cv_img,1.15)
# Show those results
show_rects(faces)
# Finally lets also try 1.25
faces = face_cascade.detectMultiScale(cv_img,1.25)
# Show those results
show_rects(faces)
image-20200612151551395 image-20200612151608049 image-20200612151622883

我们可以看到,随着我们改变比例因子,我们改变了 true and flase positives and negatives。 将 scale 设置为1.05时,我们有7个 true positives(正确识别的面孔)和3个 false negatives(存在但未检测到的面孔)和3个 false positives(其中opencv认为是面孔的非面孔)。 当我们将scale 更改为1.15时,我们会丢失误报(false positives),但也会丢失其中一个 true positives,即右边戴着帽子的女士。 当我们将其更改为1.25时,我们也会损失更多的 true positives

在机器学习和人工智能中,这实际上是一个非常有趣的现象。 不仅要在模型的精确度与不精确度之间进行权衡。 您认为这三种模式中哪一种最好?

好吧,这个问题的答案实际上是“取决于”。这取决于您为什么要检测面部,以及如何处理面部。如果您认为这些问题很有趣,则可能需要查看Applied Data Science with Python specialization Michigan offers on Coursera.。

好的,除了做广告的机会,您还注意到我们更改比例因子时发生的其他事情吗?这很微妙,但是在较小的比例因子下,处理运行的速度会花费更长的时间。这是因为小的比例因此将处理更多的subimage。这也可能会影响我们可能使用的方法。

Jupyter 对计时命令(timing commands)有很好的支持。您可能以前已经知道这一点,**在jupyter中以百分号开头的行称为“魔术函数”。**这不是普通的python-实际上是编写Jupyter预定义的函数的简便方法。看起来很像我们在上一讲中讨论过的装饰器,但是魔术功能早在装饰器成为python语言的一部分之前就已经存在了。虚拟机中的一个内置魔术功能称为 timeit ,它会重复一段python十次(默认情况下),并告诉您完成该程序所需的平均速度。

# Lets time the speed of detectmultiscale when using a scale of 1.05
%timeit face_cascade.detectMultiScale(cv_img,1.05)

您会看到这是一个巨大的差异,使用较小的比例尺时,速度大约慢两倍半!

到此结束了我们在opencv中检测面部的讨论。 您会看到,就像OCR一样,这不是一个简单(foolproof)的过程。 但是我们可以在他人在机器学习中所做的工作的基础上,并利用强大的库使我们更接近构建一揽子基于python的解决方案。 请记住,检测机制并不特定于面部,而只是我们使用的 haarcascades 训练数据。 在网络上,您将能够找到其他训练数据来检测其他物体,包括眼睛,动物等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Lecture 5.3】Opencv 面部识别 的相关文章

  • uri 警告中缺少端口:使用 Python OpenCV cv2.VideoCapture() 打开文件时出错

    当我尝试流式传输 ipcam 时 出现了如下所示的错误 tcp 000000000048c640 uri 中缺少端口 警告 打开文件时出错 build opencv modules videoio src cap ffmpeg impl h
  • opencv人脸检测示例

    当我在设备上运行应用程序时 应用程序崩溃并显示以下按摩 java lang UnsatisfiedLinkError 无法加载 detector based tracker findLibrary 返回 null 我正在使用 OpenCV
  • 如何绘制更大的边界框和仅裁剪边界框文本 Python Opencv

    我正在使用 easyocr 来检测图像中的文本 该方法给出输出边界框 输入图像如下所示 Image 1 Image 2 使用下面的代码获得输出图像 But I want to draw a Single Bigger bounding bo
  • iOS 上的 OpenCV - VideoCapture 属性始终返回 1

    我一直在尝试构建一个简单的 OpenCV iOS 应用程序 该应用程序从捆绑包中加载视频并查询其帧数 持续时间等 然后它将尝试从中获取各个帧 不幸的是 当我使用VideoCapture类中 所有属性返回值 1 然后我尝试导航到frame 1
  • 二值图像中骨架上两点之间的最短路径

    我有一个二进制图像 其中包含图像的一个像素宽度骨架 您可能基本上知道 在这个二值图像中 我在骨架上有 1 在其他地方有 0 如何找到骨架上两个非零元素之间的最短距离 路径也应该在骨架本身上 我想使用 A star 算法的 C 实现 我找到了
  • OpenCV VideoWriter 未写入 Output.avi

    我正在尝试编写一段简单的代码来获取视频 裁剪视频并写入输出文件 系统设置 OS Windows 10 Conda Environment Python Version 3 7 OpenCV Version 3 4 2 ffmpeg Vers
  • BRISK 特征检测器检测零个关键点

    下面显示的 Brisk 探测器没有给我任何关键点 有人可以提出一个问题吗 我将尝试用一些代码解释我在下面所做的事情 include opencv2 features2d features2d hpp using namespace cv u
  • Python:Urllib2 和 OpenCV

    我有一个程序 可以将图像保存在本地目录中 然后从该目录中读取图像 但我不想保存图像 我想直接从url读取它 这是我的代码 import cv2 cv as cv import urllib2 url http cache2 allposte
  • 如何将多行文本插入到框架/图像中

    我使用 C 和 OpenCV 创建了一个框架 并想在其中插入几行文本 使用以下代码 putText frame My text here cvPoint 30 30 FONT HERSHEY COMPLEX SMALL 0 8 cvScal
  • iphone opencv - 模板匹配

    我已经在我的 iphone 项目中实现了这个 OpenCV 构建 http aptogo co uk 2011 09 opencv framework for ios http aptogo co uk 2011 09 opencv fra
  • 将 OpenCV Mat 转换为数组(可能是 NSArray)

    我的 C C 技能很生疏 OpenCV 的文档也相当晦涩难懂 有没有办法获得cv Mat data属性转换为数组 NSArray 我想将其序列化为 JSON 我知道我可以使用 FileStorage 实用程序转换为 YAML XML 但这不
  • 如何使用 python 定位和读取 Data Matrix 代码

    我正在尝试读取微管底部的数据矩阵条形码 我试过libdmtx http libdmtx sourceforge net 它有 python 绑定 当矩阵的点是方形时工作得相当好 但当矩阵的点是圆形时工作得更糟 如下所示 另一个复杂问题是在某
  • HoughLinesP后如何合并线?

    My task is to find coordinates of lines startX startY endX endY and rectangles 4 lines Here is input file 我使用下一个代码 img c
  • Opencv 2.4.2 代码讲解-人脸识别

    我参考OpenCV提供的文档制作了一个人脸识别程序 可以识别多个人脸 并且工作正常 在文档中 他们制作了省略号来突出显示脸部 我不明白的是他们如何计算椭圆的中心 他们的计算如下 for int i 0 i lt faces size i P
  • opencv中如何去除二值图像噪声?

    将图像转换为二值图像 黑白 后如果有任何噪音怎么办 我消除了那些不需要的噪音 您可以看到下图的黑色区域内有一些白噪声 我该如何去除噪声 使用opencv http img857 imageshack us img857 999 blackn
  • 未加载库:@rpath/libopenblasp-r0.2.19.dylib

    我应该如何解决这个问题 Monas MacBook Pro 02 02 mona python Python 3 6 1 Anaconda custom x86 64 default May 11 2017 13 04 09 GCC 4 2
  • Haar级联正例图像大小调整

    我正在迈出第一步 为自定义对象识别创建 haar 级联 我花了时间获取大量数据并编写了一些预处理脚本以将视频转换为帧 我的下一步是裁剪感兴趣的对象 以创建一些积极的训练示例 我有几个问题 我确实在网上寻找答案 我有点困惑 我读到我应该致力于
  • 将 CvSeq 保存到数组

    我对 OpenCV 文档有点迷失 我想将 cvFindContours 返回的 CvSeq 保存到一个数组中 据我了解它将返回 CvContour 的 seq 但我找不到它包含的内容 我应该保存其中的哪些部分 稍后我可以迭代它并说调用 cv
  • 使用 Racket FFI 进行快速阵列访问

    我正在尝试在 Racket 中编写 OpenCV FFI 并达到了需要有效操作数组的地步 然而 我所有使用 Racket FFI 访问数组的尝试都会导致代码效率非常低 有没有办法使用 FFI 快速访问 C 数组 在 Racket 中 这种类
  • CV_MAT_ELEM 中的编译错误

    调用estimateRigidTransform 的结果是我得到一个名为 trans 的cv Mat 对象 为了检索其包含的矩阵 我尝试以这种方式访问 其元素 for i 0 i lt 2 i for j 0 j lt 3 j mtx j

随机推荐

  • 基于特征模型的全系数自适应控制

    摘要 xff1a 首先推导了全系数和等于1的证明过程 xff0c 分析了等效时间常数的概念 xff0c 然后推导了递推最小二乘公式并用于参数辨识的方法 xff0c 最后给几个仿真的例子 全系数之和等于1 被控对象用微分方程 y n
  • raylib一些示例代码

    摘要 xff1a 几种相机视角 3D预览图视角 xff1a 鼠标拖动 xff0c 滚轮缩放 只能沿着中心点 第一视角 xff1a WSAD分别控制视角的前后左右移动 xff0c EQ分别控制上下移动 xff0c 滚轮控制移动速度 画正方体线
  • gnome session 中的开机启动程序配置文件

    我找了很久才找到的 xff1a 管理员状态下 xff1a linux Blue home library config autostart ls gnome terminal desktop stardict desktop 我开机启动的两
  • 使用深度Q网络(Deep Q Network)学习控制倒立摆

    使用深度Q网络 Deep Q Network 学习控制单摆 原文 xff1a https qiita com ashitani items bb393e24c20e83e54577 摘要 xff1a 我们将尝试使用Deep Q网络 xff0
  • python多次调用exe文件运行不同的结果

    摘要 xff1a 有个C 43 43 项目是读取配置参数文件并打印对应的结果 xff0c 后来需要多次修改配置文件并运行 xff0c 于是想到写个python脚本执行这一过程 写一个测试项目 xff0c 项目结构如下 xff1a 根目录 m
  • Python通过SWIG调用C++时出现的ImportError问题解析

    摘要 win10系统 xff0c 编译器为mingw xff0c 按照教程封装C 43 43 的一个类并用python调用 xff0c 一步步进行直到最后一步运行python代码时 xff0c 在python代码中import exampl
  • 基于Android设备获取USB外接摄像头的图像

    目录 背景开发环境硬件软件 简介那我们开始吧导入项目布局 权限与初始化MainActivity java运行时遇到的问题 运行结果其他 背景 本人在读研期间接到的项目 xff0c 需要用一个工业内窥镜 xff08 支持USB和Type C接
  • Python爬取百度搜索结果(标题,摘要,链接)

    近期想要爬取百度搜索的结果 xff0c 网上的教程一直没有找到可以直接用的 xff0c 尝试了几个小时终于摸索出了可以用的代码 主要的问题在于 url 的形式 xff0c 之前的教程一般是这种形式 xff1a url 61 39 https
  • ubuntu 14.04 安装chrome,无法正常启动解决(亲测)。

    1 进入 Ubuntu 14 04 桌面 xff0c 按下 Ctrl 43 Alt 43 t 键盘组合键 xff0c 启动终端 2 在终端中 xff0c 输入以下命令 xff1a sudo wget https repo fdzh org
  • 搭建ftp并设置用户名和密码

    第一步 xff1a 启用 IIS 服务 步骤一 打开控制面板 点击 34 开始 34 xff08 或者按键盘上的微软徽标键 xff0c 通常在左侧 Ctrl 键和 Alt 键之间 xff09 xff0c 在打开的 34 开始菜单 34 中
  • FTPClient ftp.storeFile上传文件时服务器无响应的原因

    用FTPClient做FTP上传 xff0c 由quartz来定时运行 xff08 2分钟一次 xff09 xff0c 之前在生产环境调试没问题 xff0c 一些时间后现场反馈不能上传了 xff0c 当出现10个扫描文件的日志后就不再出现了
  • 解决Unable to add window -- token android.os.BinderProxy is not valid; is your activity running?

    原因一般是展示dialog的时候用的是异步 xff0c 或者是另开一个线程 当Activity已经关闭 xff0c 才调用dialog show xff0c 此时Activity已经不存在 xff0c 必然报错 解决办法 xff1a 可以添
  • 在PATH中加入本地路径(Adding a Directory to the Path)

    Executive Summary Adding a directory to the path of a user or all users would seem trivial but in fact it isn 39 t The b
  • SpringBoot中如何进行统一异常处理

    如何在SpringBoot项目里进行统一异常处理 需要了解的知识 64 ControllerAdvice的作用 1 处理前 异常代码 span class token comment 根据id获取医院设置 64 param id 查看的id
  • Ai智能时代即将到来,替代程序员还是相辅相成,我们拭目以待

    AI是否会替代前端程序员 xff1f 这是一个让很多人感到担忧的问题 随着AI技术的发展 xff0c 越来越多的工作被自动化 前端开发是否也会面临被取代的危机呢 xff1f 前端开发是指使用HTML CSS JavaScript等技术 xf
  • 【Lecture 4.3】Test Cases and Exception

    18 1 Introduction Test Cases Test Cases以一种可以自动检查的方式表达了对程序的需求 具体地说 xff0c 测试test断言asserts 程序在其执行的某个特定点上的状态 我们之前曾建议 xff0c 在
  • 【Lecture 5.1】PIL module

    文章目录 PIL module使用 PIL 打开并展示一个图片copysave 96 filter 96 function 96 crop 96 裁剪ImageDraw图像亮度图像整合模块介绍参考 ImageDraw text 绘制文字As
  • 【Lecture 5.2】The (Py)Tesseract Library

    文章目录 Lecture The Py Tesseract Library对文本图像的处理改变图片大小greyscale 灰度图binarization 二值图 Tesseract and Photographs 对图像的OCR识别Jupy
  • 【Lecture 5.3】Release the Kraken

    文章目录 Release the Kraken Release the Kraken 我们要看的下一个库是 Kraken xff0c 它是由巴黎PSL大学开发的 我们将使用Kraken的目的是在给定图像中检测文本行来作为的边界框 xff08
  • 【Lecture 5.3】Opencv 面部识别

    文章目录 Comparing Image Data StructuresOpenCV Comparing Image Data Structures OpenCV支持读取大多数文件格式的图像 xff0c 例如JPEG xff0c PNG和T