OpenCV-Python-Tutorial[5]

参考:https://github.com/makelove/OpenCV-Python-Tutorial


  • ch41-背景减除
    • 2-BackgroundSubtractorMOGpy
    • 3-BackgroundSubtractorMOG2py
    • 4-morphologyExpy
  • ch42-摄像机标定
    • 21-设置-findChessboardCornerspy
    • 其他py
  • ch43-姿势估计
    • calib3dpy
  • ch44-对极几何
    • codepy
  • ch45-立体图像中的深度地图
    • codepy
  • ch46-机器学习-K近邻
    • 1-kNNpy
    • 2-使用kNN对手写数字OCRpy
    • 2-英文字母的OCRpy
    • knn-find_nearestpy
    • 同时预测数字和英文字母1py
    • 预测手写数字1py
  • ch47-支持向量机
    • 2-使用SVM进行-手写数据OCRpy
  • ch48-K值聚类
    • 22_仅有一个特征的数据py
    • 22-含有多个特征的数据py
    • 23_颜色量化py
    • 23_颜色量化2py
  • ch49-计算摄影学-图像去噪
    • 1-fastNlMeansDenoisingColoredpy
    • 2-fastNlMeansDenoisingMultipy
  • ch50-2-HDR-HighDynamicRange
    • HDRpy
  • ch50-图像修补
    • inpaintpy
  • ch51-对象检测-使用Haar分类器进行面部检测
    • CascadeClassifier级联分类器py
    • 行人检测
      • Pedestrian_Detection_videopy
      • Pedestrian_Detection1py
  • ch52-Python_C_binding_in_OpenCV

ch41-背景减除

41.2-BackgroundSubtractorMOG.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午6:12
# @Author  : play4fun
# @File    : 41.2-BackgroundSubtractorMOG.py
# @Software: PyCharm

"""
41.2-BackgroundSubtractorMOG.py:
在很多基础应用中背景检出 是一个 常  的步 。例如 客统  使 用一个 态摄像头来 录 入和离开房 的人数 或者是交 摄像头   提 取交 工具的信息等。在所有的 些例子中  先 将人或 单独提取出来。 技术上来  我们  从 止的背景中提取移动的前景。

但是我们现在讲的背景建模是基于时间序列的
 因此每一个像素点所在的位置在整个时间序列中 就会有很多值 从而构成一个分布。
"""

import numpy as np
import cv2

# cap = cv2.VideoCapture('../data/vtest.avi')
cap = cv2.VideoCapture(0)#笔记本摄像头

fgbg = cv2.bgsegm.createBackgroundSubtractorMOG()
# 可选参数 比如 进行建模场景的时间长度 高斯混合成分的数量-阈值等

while True:
    ret, frame = cap.read()
    # frame = cv2.flip(frame, flipCode=1)  # 左右翻转

    fgmask = fgbg.apply(frame)

    cv2.imshow('frame', fgmask)
    k = cv2.waitKey(1) #& 0xff
    if k == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

41.3-BackgroundSubtractorMOG2.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午6:16
# @Author  : play4fun
# @File    : 41.3-BackgroundSubtractorMOG2.py
# @Software: PyCharm

"""
41.3-BackgroundSubtractorMOG2.py:
这个算法的一个特点是它为每一个像素选择一个合适数目的 斯分布。
上一个方法中我们使用是 K 给斯分 布 。
 这样就会对由于亮度等发生变化引起的场景变化产生更好的适应。
和前面一样我们  创建一个背景对 。但在  我们我们可以 择是否 检测阴影。如果 detectShadows = True 默认值
它就会检测并将影子标记出来 但是 样做会降低处理速度。影子会 标记为灰色。
"""

import numpy as np
import cv2

# cap = cv2.VideoCapture('../data/vtest.avi')
cap = cv2.VideoCapture(0)#笔记本摄像头

fgbg = cv2.createBackgroundSubtractorMOG2()
while True:
    ret, frame = cap.read()
    # frame = cv2.flip(frame, flipCode=1)  # 左右翻转

    fgmask = fgbg.apply(frame)

    cv2.imshow('frame', fgmask)
    k = cv2.waitKey(30) #& 0xff
    if k == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

41.4-morphologyEx.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午6:18
# @Author  : play4fun
# @File    : 41.4-BackgroundSubtractorGMG.py
# @Software: PyCharm

"""
41.4-BackgroundSubtractorGMG.py:

它使用前 很少的图像   为前 120 帧   背景建模。使用了概率前 景估 算法 使用 叶斯估  定前景 。 是一种自 应的估  新 察到的 对 比旧的对 具有更 的权  从而对光照变化产生 应。一些形态学操作 如开 算  算等 用来 去不  的噪 。在前几帧图像中你会得到一个  色窗口。
  对结果  形态学开 算对与去 噪声很有帮助。
"""

import numpy as np
import cv2

# cap = cv2.VideoCapture('../data/vtest.avi')
cap = cv2.VideoCapture(0)#笔记本摄像头

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
fgbg = cv2.bgsegm.createBackgroundSubtractorGMG()

counter=0
while True:
    ret, frame = cap.read()
    fgmask = fgbg.apply(frame)
    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)

    cv2.imshow('frame', fgmask)#前 120 帧
    counter+=1
    print(counter)

    k = cv2.waitKey(1)  # & 0xff
    if k == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

ch42-摄像机标定

42.2.1-设置-findChessboardCorners.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午6:21
# @Author  : play4fun
# @File    : 42.2.1-设置-findChessboardCorners.py
# @Software: PyCharm

"""
42.2.1-设置-findChessboardCorners.py:

径向畸变和切想畸变
摄像机的内部和外部参数。 内部参数是摄像机特异的。它包括的信息有焦 ( fx, fy) 光学中心 (cx, cy)  等。 也 称为摄像机矩阵。它完全取决于摄像机自  只需要计算一次 以后就可以已知使用了。

至少需要10张图案模式来进行摄像机标定
3D 点 称为对象点, 2D 图像点 称为图像点

除了使用棋盘之外 我们 可以使用环形格子
使用函数 cv2.findCirclesGrid() 来找图案。
据说使用环形格子只需要很少的图像 就可以了。

"""

import numpy as np
import cv2
import glob

# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((6 * 7, 3), np.float32)
objp[:, :2] = np.mgrid[0:7, 0:6].T.reshape(-1, 2)
# Arrays to store object points and image points from all the images.
objpoints = []  # 3d point in real world space
imgpoints = []  # 2d points in image plane.
images = glob.glob('../data/left*.jpg')
images += glob.glob('../data/right*.jpg')
for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # Find the chess board corners
    ret, corners = cv2.findChessboardCorners(gray, (7, 6), None)
    # If found, add object points, image points (after refining them)
    if ret == True:
        objpoints.append(objp)
        corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
        imgpoints.append(corners)
        # Draw and display the corners
        cv2.drawChessboardCorners(img, (7, 6), corners2, ret)
        cv2.imshow('img', img)
        cv2.waitKey(500)
cv2.destroyAllWindows()

其他.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午6:29
# @Author  : play4fun
# @File    : 其他.py
# @Software: PyCharm

"""
其他.py:
"""
import cv2

# 标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

# 畸变校正
img = cv2.imread('left12.jpg')
h, w = img.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h))

# 使用 cv2.undistort()  是最简单的方法。只 使用这个函数和上面得到 的 ROI 对结果进行裁剪。

# undistort
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)
# crop the image
x, y, w, h = roi
dst = dst[y:y + h, x:x + w]
cv2.imwrite('calibresult.png', dst)

# 使用 remapping  应 属于 曲线救国 了。 先我们 找到从畸变图像到畸变图像的映射方程。再使用 重映射方程
# undistort
mapx, mapy = cv2.initUndistortRectifyMap(mtx, dist, None, newcameramtx, (w, h), 5)
dst = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)
# crop the image
x, y, w, h = roi
dst = dst[y:y + h, x:x + w]
cv2.imwrite('calibresult.png', dst)
# 你会发现结果图像中所有的边界 变直了

# 反向投影误差
# 我们可以利用反向投影 差对我们找到的参数的准确性  估 。
# 得到的 结果越接近 0 越好。有了内部参数 畸变参数和旋 变换矩  我们就可以使 用 cv2.projectPoints() 将对象点转换到图像点。
# 然后就可以 算变换得到 图像与角点检测算法的绝对差了。
# 然后我们计算所有标定图像的误差平均值。
mean_error = 0
for i in range(len(objpoints)):
    imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
    error = cv2.norm(imgpoints[i], imgpoints2, cv2.NORM_L2) / len(imgpoints2)
    mean_error += error
print("total error: ", mean_error / len(objpoints))

ch43-姿势估计

calib3d.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午6:44
# @Author  : play4fun
# @File    : calib3d.py
# @Software: PyCharm

"""
calib3d.py:
在图像中绘制一些 2D 的线条来产生 3D 的效果

在棋盘的第一个角点绘制 3D 坐标  X Y Z
 X  为蓝色 Y  为绿色 Z  为红色。
 在视觉效果上来看 Z 轴应 是垂直于棋盘平面的。
"""

import cv2
import numpy as np
import glob

# Load previously saved data摄像机矩阵和畸变系数
with np.load('B.npz') as X:
    mtx, dist, _, _ = [X[i] for i in ('mtx', 'dist', 'rvecs', 'tvecs')]


# 函数 draw 它的参数有棋盘上的角点
#  使用 cv2.findChessboardCorners() 得到
#  绘制的 3D 坐标轴上的点
def draw(img, corners, imgpts):
    corner = tuple(corners[0].ravel())
    img = cv2.line(img, corner, tuple(imgpts[0].ravel()), (255, 0, 0), 5)
    img = cv2.line(img, corner, tuple(imgpts[1].ravel()), (0, 255, 0), 5)
    img = cv2.line(img, corner, tuple(imgpts[2].ravel()), (0, 0, 255), 5)
    return img


# 渲染一个立方体
def draw_cube(img, corners, imgpts):
    imgpts = np.int32(imgpts).reshape(-1, 2)
    # draw ground floor in green
    img = cv2.drawContours(img, [imgpts[:4]], -1, (0, 255, 0), -3)
    # draw pillars in blue color
    for i, j in zip(range(4), range(4, 8)):
        img = cv2.line(img, tuple(imgpts[i]), tuple(imgpts[j]), (255), 3)
    # draw top layer in red color
    img = cv2.drawContours(img, [imgpts[4:]], -1, (0, 0, 255), 3)
    return img


# 设置终止条件 对象点 棋盘上的 3D 角点 和坐标轴点
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objp = np.zeros((6 * 7, 3), np.float32)
objp[:, :2] = np.mgrid[0:7, 0:6].T.reshape(-1, 2)
axis = np.float32([[3, 0, 0], [0, 3, 0], [0, 0, -3]]).reshape(-1, 3)
# 渲染一个立方体
# axis = np.float32([[0, 0, 0], [0, 3, 0], [3, 3, 0], [3, 0, 0],
#                    [0, 0, -3], [0, 3, -3], [3, 3, -3], [3, 0, -3]])

'''
很 常一样我们  加 图像。搜寻 7x6 的格子 如果发现 我们就把它 优化到亚像素级。然后使用函数:cv2.solvePnPRansac() 来 算旋 和变 换。但我们有了变换矩 之后 我们就可以利用它们将 些坐标 点映射到图 像平 中去。简单来  我们在图像平 上找到了与 3D 空 中的点 3,0,0  ,(0,3,0),(0,0,3) 相对应的点。然后我们就可以使用我们的函数 draw() 从图像 上的第一个 点开始绘制 接 些点的直线了。搞定   
'''
for fname in glob.glob('../data/left*.jpg'):
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, corners = cv2.findChessboardCorners(gray, (7, 6), None)
    if ret == True:
        corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
        # Find the rotation and translation vectors.
        ret, rvecs, tvecs, inliers = cv2.solvePnP(objp, corners2, mtx, dist)
        # project 3D points to image plane
        imgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)
        img = draw(img, corners2, imgpts)
        cv2.imshow('img', img)
        k = cv2.waitKey(0) & 0xFF
        if k == ord('s'):
            cv2.imwrite(fname[:6] + '.png', img)
cv2.destroyAllWindows()

#如果你对计算机图形学感兴趣的  为了增加图像的真实性 你可以使用 OpenGL 来渲染更复杂的图形。 下一个目标

ch44-对极几何

code.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午6:57
# @Author  : play4fun
# @File    : code.py
# @Software: PyCharm

"""
code.py:多视角几何基础,极点 极线 对极约束 对极平面

在我们使用针孔相机时 我们会丢失大量重要的信息
 比如 图像的深度  或者 图像上的点和摄像机的距离
因为这是一个从 3D 到 2D 的转换。
重要的问题:
 使用这样的摄像机我们能否计算出深度信息呢?
  答案 就是使用多个相机。
  我们的眼睛就是这样工作的 使用两个摄像机 两个眼睛
称为立体视角

三角测量

本征矩阵 E 和基础矩阵 F

点越多越好 可以使用 RANSAC 算法得到更加稳定的结果

使用 SIFT 描述符 FLANN 匹配器和比值检测
"""

import cv2
import numpy as np
from matplotlib import pyplot as plt


# 找到极线
def drawlines(img1, img2, lines, pts1, pts2):
    ''' img1 - image on which we draw the epilines for the points in img2
        lines - corresponding epilines '''
    r, c = img1.shape
    img1 = cv2.cvtColor(img1, cv2.COLOR_GRAY2BGR)
    img2 = cv2.cvtColor(img2, cv2.COLOR_GRAY2BGR)
    for r, pt1, pt2 in zip(lines, pts1, pts2):
        color = tuple(np.random.randint(0, 255, 3).tolist())
        x0, y0 = map(int, [0, -r[2] / r[1]])
        x1, y1 = map(int, [c, -(r[2] + r[0] * c) / r[1]])
        img1 = cv2.line(img1, (x0, y0), (x1, y1), color, 1)
        img1 = cv2.circle(img1, tuple(pt1), 5, color, -1)
        img2 = cv2.circle(img2, tuple(pt2), 5, color, -1)
    return img1, img2


img1 = cv2.imread('myleft.jpg', 0)  # queryimage # left image
img2 = cv2.imread('myright.jpg', 0)  # trainimage # right image
sift = cv2.xfeatures2d.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1, None)#TODO
kp2, des2 = sift.detectAndCompute(img2, None)

# FLANN parameters
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1, des2, k=2)
good = []
pts1 = []
pts2 = []
# ratio test as per Lowe's paper
for i, (m, n) in enumerate(matches):
    if m.distance < 0.8 * n.distance:
        good.append(m)
        pts2.append(kp2[m.trainIdx].pt)
        pts1.append(kp1[m.queryIdx].pt)
        # 匹配点列表,用它来计算【基础矩阵】
        pts1 = np.int32(pts1)
        pts2 = np.int32(pts2)
        F, mask = cv2.findFundamentalMat(pts1, pts2, cv2.FM_LMEDS)
        # We select only inlier points
        pts1 = pts1[mask.ravel() == 1]
        pts2 = pts2[mask.ravel() == 1]
        # 从两幅图像中计算并绘制极线
        # Find epilines corresponding to points in right image (second image) and
        # drawing its lines on left image
        lines1 = cv2.computeCorrespondEpilines(pts2.reshape(-1, 1, 2), 2, F)
        lines1 = lines1.reshape(-1, 3)
        img5, img6 = drawlines(img1, img2, lines1, pts1, pts2)
        # Find epilines corresponding to points in left image (first image) and
        # drawing its lines on right image
        lines2 = cv2.computeCorrespondEpilines(pts1.reshape(-1, 1, 2), 1, F)
        lines2 = lines2.reshape(-1, 3)
        img3, img4 = drawlines(img2, img1, lines2, pts2, pts1)
        plt.subplot(121), plt.imshow(img5)
        plt.subplot(122), plt.imshow(img3)
        plt.show()

#从上图可以看出所有的极线都汇聚以图像外的一点  这个点就是极点。
# 为了得到更好的结果 我们应 使用分辨率比较高的图像和 non-planar 点

ch45-立体图像中的深度地图

code.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午7:09
# @Author  : play4fun
# @File    : code.py
# @Software: PyCharm

"""
code.py:
下图左侧为原始图像 右侧为深度图像。
如图所示 结果中有很大的噪音。
通过调整 numDisparities 和 blockSize 的值 我们会得到更好的结果。
"""

import numpy as np
import cv2
from matplotlib import pyplot as plt

imgL = cv2.imread('tsukuba_l.png', 0)
imgR = cv2.imread('tsukuba_r.png', 0)

#参数不对?
stereo = cv2.StereoBM_create(numDisparities=16, blockSize=15)
# stereo = cv2.StereoBM_create(numDisparities=16, blockSize=21)
disparity = stereo.compute(imgL, imgR)

#不行
plt.imshow(disparity, 'gray')
plt.show()

# cv2.imshow('disparity',disparity)
# cv2.waitKey(0)

ch46-机器学习-K近邻

1-kNN.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午7:17
# @Author  : play4fun
# @File    : 1-kNN.py
# @Software: PyCharm

"""
1-kNN.py:

k 的取值最好为奇数
根据 k 个 最近邻居进行分类的方法 称为 kNN

权重
距离近的具有更高的权重, 距离远的权重更低

"""

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Feature set containing (x,y) values of 25 known/training data
trainData = np.random.randint(0, 100, (25, 2)).astype(np.float32)
# Labels each one either Red or Blue with numbers 0 and 1
responses = np.random.randint(0, 2, (25, 1)).astype(np.float32)
# Take Red families and plot them
red = trainData[responses.ravel() == 0]

plt.scatter(red[:, 0], red[:, 1], 80, 'r', '^')
# Take Blue families and plot them
blue = trainData[responses.ravel() == 1]

plt.scatter(blue[:, 0], blue[:, 1], 80, 'b', 's')
plt.show()

# 测试数据被标记为绿色
# # 回值包括 
# 1. 由 kNN算法计算得到的测 数据的类别标志0或1 。
# 如果你想使用最近邻算法 只需 将 k  置为 1 k 就是最近邻的数目。
# 2. k 个最近邻居的类别标志。
# 3. 每个最近邻居到测 数据的 离。
newcomer = np.random.randint(0, 100, (1, 2)).astype(np.float32)
plt.scatter(newcomer[:, 0], newcomer[:, 1], 80, 'g', 'o')
knn = cv2.ml.KNearest_create()
knn.train(trainData, cv2.ml.ROW_SAMPLE, responses)
ret, results, neighbours, dist = knn.findNearest(newcomer, 3)

print("result: ", results, "\n")
print("neighbours: ", neighbours, "\n")
print("distance: ", dist)
plt.show()

# 如果我们有大 的数据   测  可以直接传入一个数组。对应的结果 同样也是数组

# 10 new comers
newcomers = np.random.randint(0, 100, (10, 2)).astype(np.float32)
ret, results, neighbours, dist = knn.findNearest(newcomer, 3)
# The results also will contain 10 labels.

2-使用kNN对手写数字OCR.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午7:32
# @Author  : play4fun
# @File    : 2-使用kNN对手写数字OCR.py
# @Software: PyCharm

"""
2-使用kNN对手写数字OCR.py:
"""

# 准备数据

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('../data/digits.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Now we split the image to 5000 cells, each 20x20 size
cells = [np.hsplit(row, 100) for row in np.vsplit(gray, 50)]

# Make it into a Numpy array. It size will be (50,100,20,20)
x = np.array(cells)
# Now we prepare train_data and test_data.
train = x[:, :50].reshape(-1, 400).astype(np.float32)  # Size = (2500,400)
test = x[:, 50:100].reshape(-1, 400).astype(np.float32)  # Size = (2500,400)

# Create labels for train and test data
k = np.arange(10)
train_labels = np.repeat(k, 250)[:, np.newaxis]
test_labels = train_labels.copy()

# Initiate kNN, train the data, then test it with test data for k=1
knn = cv2.ml.KNearest_create()
knn.train(train, cv2.ml.ROW_SAMPLE, train_labels)
ret, result, neighbours, dist = knn.findNearest(test, k=5)

# Now we check the accuracy of classification
# For that, compare the result with test_labels and check which are wrong
matches = result == test_labels
correct = np.count_nonzero(matches)
accuracy = correct * 100.0 / result.size
print('准确率', accuracy)  # 准确率91.76%


# save the data
np.savez('knn_data.npz', train=train, train_labels=train_labels,test=test,test_labels=test_labels)

# Now load the data
with np.load('knn_data_num.npz') as data:
    print(data.files)
    train = data['train']
    train_labels = data['train_labels']
    test = data['test']
    test_labels = data['test_labels']


#TODO 怎样预测数字?
retval, results=knn.predict(test[1003:1005])
# Docstring: predict(samples[, results[, flags]]) -> retval, results
print(retval, results)#(4.0, array([[ 4.],[ 4.]], dtype=float32))
#对比
cv2.imwrite('test[1005].jpg',test[1005].reshape((20,20)))

2-英文字母的OCR.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午7:35
# @Author  : play4fun
# @File    : 2-英文字母的OCR.py
# @Software: PyCharm

"""
2-英文字母的OCR.py:
"""

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Load the data, converters convert the letter to a number
data = np.loadtxt('../data/letter-recognition.data', dtype='float32', delimiter=',',
                  converters={0: lambda ch: ord(ch) - ord('A')})#20000个
# split the data to two, 10000 each for train and test
train, test = np.vsplit(data, 2)
# split trainData and testData to features and responses
responses, trainData = np.hsplit(train, [1])
labels, testData = np.hsplit(test, [1])

# Initiate the kNN, classify, measure accuracy.
knn = cv2.ml.KNearest_create()
knn.train(trainData, cv2.ml.ROW_SAMPLE, responses)
ret, result, neighbours, dist = knn.findNearest(testData, k=5)

correct = np.count_nonzero(result == labels)
accuracy = correct * 100.0 / 10000
print('准确率', accuracy)#93.06
#准确率 到了 93.22%。同样你可以  增加训练样本的数量来提 准确率。


# save the data
np.savez('knn_data_alphabet.npz', train_alphabet=train, train_labels_alphabet=responses,test_alphabet=testData,test_labels_alphabet=labels)

#怎样预测字母?跟预测数字的一样

knn-find_nearest.py

# -*- coding: utf-8 -*-
# @Time    : 2017/8/8 12:33
# @Author  : play4fun
# @File    : knn-find_nearest.py
# @Software: PyCharm

"""
knn-find_nearest.py:
http://www.bogotobogo.com/python/OpenCV_Python/python_opencv3_Machine_Learning_Classification_K-nearest_neighbors_k-NN.php
"""

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Feature set containing (x,y) values of 25 known/training data
trainData = np.random.randint(0, 100, (25, 2)).astype(np.float32)

# Labels each one either Red or Blue with numbers 0 and 1
responses = np.random.randint(0, 2, (25, 1)).astype(np.float32)

# plot Reds
red = trainData[responses.ravel() == 0]
plt.scatter(red[:, 0], red[:, 1], 80, 'r', '^')

# plot Blues
blue = trainData[responses.ravel() == 1]
plt.scatter(blue[:, 0], blue[:, 1], 80, 'b', 's')

# CvKNearest instance
# knn = cv2.KNearest()
knn = cv2.ml.KNearest_create()
# trains the model
knn.train(trainData, responses)#TODO
#TypeError: only length-1 arrays can be converted to Python scalars


# New sample : (x,y)
newcomer = np.random.randint(0, 100, (1, 2)).astype(np.float32)
plt.scatter(newcomer[:, 0], newcomer[:, 1], 80, 'g', 'o')

# Finds the 3nearest  neighbors and predicts responses for input vectors
ret, results, neighbours, dist = knn.find_nearest(newcomer, 3)

print("result: ", results, "\n")
print("neighbours: ", neighbours, "\n")
print("distance: ", dist)

plt.show()

同时预测数字和英文字母1.py

# -*- coding: utf-8 -*-
# @Time    : 2017/8/10 17:59
# @Author  : play4fun
# @File    : 同时预测数字和英文字母1.py
# @Software: PyCharm

"""
同时预测数字和英文字母1.py:
"""



import numpy as np
import cv2
from matplotlib import pyplot as plt

with np.load('knn_data_num.npz') as data:
    print(data.files)  # ['train', 'train_labels', 'test', 'test_labels']
    train = data['train']
    train_labels = data['train_labels']
    test = data['test']
    test_labels = data['test_labels']

with np.load('knn_data_alphabet.npz') as data:
    print(data.files)
    train_alphabet = data['train_alphabet']
    train_labels_alphabet = data['train_labels_alphabet']
    test_alphabet = data['test_alphabet']
    test_labels_alphabet = data['test_labels_alphabet']

# shape不一致,无法合并
# train.shape #(2500, 400)
# train_alphabet.shape#(10000, 17)
# print('合并-数字-字母数据')
# train = np.append(train, train_alphabet)
# tratrain_labelsin = np.append(train_labels,train_labels_alphabet)
# test = np.append(test, test_alphabet)
# test_labels = np.append(test_labels, test_labels_alphabet)

print('加载KNN,数据')
knn = cv2.ml.KNearest_create()
knn.train(train, cv2.ml.ROW_SAMPLE, train_labels)
knn.train(train_alphabet, cv2.ml.ROW_SAMPLE, train_labels_alphabet)

ret, result, neighbours, dist = knn.findNearest(
    test, k=5)# shape不一致
#出错,knearest.cpp:325: error: (-215) test_samples.type() == CV_32F && test_samples.cols == samples.cols in function findNearest

预测手写数字1.py

# -*- coding: utf-8 -*-
# @Time    : 2017/8/8 11:57
# @Author  : play4fun
# @File    : 预测手写数字1.py
# @Software: PyCharm

"""
预测手写数字1.py:

验证码
https://login.bthhotels.com/
"""

import numpy as np
import cv2
from matplotlib import pyplot as plt

with np.load('knn_data_num.npz') as data:
    print(data.files)  # ['train', 'train_labels', 'test', 'test_labels']
    train = data['train']
    train_labels = data['train_labels']
    test = data['test']
    test_labels = data['test_labels']

print('加载KNN,数据')
knn = cv2.ml.KNearest_create()
knn.train(train, cv2.ml.ROW_SAMPLE, train_labels)

# 加载相片
print('加载相片')
img2 = cv2.imread('2.png', 0)
gray2 = cv2.resize(img2, (20, 20))
# gray2=gray2.reshape((400,))
gray21 = gray2.reshape((-1, 400)).astype(np.float32)

img6 = cv2.imread('6.png', 0)
gray6 = cv2.resize(img6, (20, 20))
# gray2=gray2.reshape((400,))
gray61 = gray6.reshape((-1, 400)).astype(np.float32)

g2 = np.append(gray21, gray61)
g3 = g2.reshape((2, 400))

# 预测
retval, results = knn.predict(g3)
print(retval, results)  # 不准确
# (0.0, array([[ 0.],
#         [ 5.]], dtype=float32))

ch47-支持向量机

47.2-使用SVM进行-手写数据OCR.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午8:23
# @Author  : play4fun
# @File    : 47.2-使用SVM进行-手写数据OCR.py
# @Software: PyCharm

"""
47.2-使用SVM进行-手写数据OCR.py:
"""

import cv2
import numpy as np

SZ = 20
bin_n = 16  # Number of bins
affine_flags = cv2.WARP_INVERSE_MAP | cv2.INTER_LINEAR


# 使用方向梯度直方图Histogram of Oriented Gradients  HOG 作为特征向量
def deskew(img):
    m = cv2.moments(img)
    if abs(m['mu02']) < 1e-2:
        return img.copy()
    skew = m['mu11'] / m['mu02']
    M = np.float32([[1, skew, -0.5 * SZ * skew], [0, 1, 0]])
    img = cv2.warpAffine(img, M, (SZ, SZ), flags=affine_flags)
    return img


# 计算图像 X 方向和 Y 方向的 Sobel 导数
def hog(img):
    gx = cv2.Sobel(img, cv2.CV_32F, 1, 0)
    gy = cv2.Sobel(img, cv2.CV_32F, 0, 1)
    mag, ang = cv2.cartToPolar(gx, gy)
    bins = np.int32(bin_n * ang / (2 * np.pi))  # quantizing binvalues in (0...16)
    bin_cells = bins[:10, :10], bins[10:, :10], bins[:10, 10:], bins[10:, 10:]
    mag_cells = mag[:10, :10], mag[10:, :10], mag[:10, 10:], mag[10:, 10:]
    hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]
    hist = np.hstack(hists)  # hist is a 64 bit vector
    return hist


# 最后 和前 一样 我们将大图分割成小图。使用每个数字的前 250 个作 为训练数据
#  后 250 个作为测试数据
img = cv2.imread('../data/digits.png', 0)

cells = [np.hsplit(row, 100) for row in np.vsplit(img, 50)]
# First half is trainData, remaining is testData
train_cells = [i[:50] for i in cells]
test_cells = [i[50:] for i in cells]

deskewed = [map(deskew, row) for row in train_cells]
# deskewed = [deskew(row) for row in train_cells]
# deskewed = map(deskew, train_cells)
hogdata = [map(hog, row) for row in deskewed]
# hogdata = [hog(row) for row in deskewed]
# hogdata = map(hog, deskewed)

trainData = np.float32(hogdata).reshape(-1, 64)
responses = np.float32(np.repeat(np.arange(10), 250)[:, np.newaxis])

svm = cv2.ml.SVM_create()
svm.setKernel(cv2.ml.SVM_LINEAR)
svm.setType(cv2.ml.SVM_C_SVC)
svm.setC(2.67)
svm.setGamma(5.383)
svm.train(trainData, cv2.ml.ROW_SAMPLE, responses)
svm.save('svm_data.dat')

deskewed = [map(deskew, row) for row in test_cells]
hogdata = [map(hog, row) for row in deskewed]
testData = np.float32(hogdata).reshape(-1, bin_n * 4)

result = svm.predict(testData)
mask = result == responses
correct = np.count_nonzero(mask)
print(correct * 100.0 / result.size)
# 94%

ch48-K值聚类

48.2.2_仅有一个特征的数据.py

# -*- coding: utf-8 -*-
# @Time    : 2017/2/24 下午3:00
# @Author  : play4fun
# @File    : 48.2.2_仅有一个特征的数据.py
# @Software: PyCharm

"""
48.2.2_仅有一个特征的数据.py:

输入参数
1. samples: 应 是 np.float32 类型的数据 每个特征应 放在一列。
2. nclusters(K): 聚类的最终数目。
3. criteria: 终止 代的条件。当条件满 时 算法的 代终止。它应 是 一个含有 3 个成员的元组 它们是 typw max_iter epsilon
4. attempts: 使用不同的 始标 来执 算法的次数。算法会 回紧密度 最好的标 。紧密度也会作为 出  回。
5. flags 用来 置如何 择 始 心。 常我们有两个 择 cv2.KMEANS_PP_CENTERS 和 cv2.KMEANS_RANDOM_CENTERS。

输出参数
1. compactness 紧密度  回每个点到相应 心的 离的平方和。
2. labels 标志数组 与上一节提到的代码相同  每个成员 标 为 0 1 等
3. centers 由聚类的中心组成的数组

"""

# 假 我们有一组数据 每个数据只有一个特征 1 维 。例如前 的 T 恤    我们只使用人们的  来决定 T 恤的大小。
# 我们先来产生一些 机数据 并使用 Matplotlib 将它们绘制出来。

import numpy as np
import cv2
from matplotlib import pyplot as plt

x = np.random.randint(25, 100, 25)
y = np.random.randint(175, 255, 25)
z = np.hstack((x, y))
z = z.reshape((50, 1))
z = np.float32(z)
plt.hist(z, 256, [0, 256]), plt.show()
# 现在我们有一个 度为 50 取值范围为 0 到 255 的向量z。我已经将向量z  重排 将它变成了一个列向量。
# 当每个数据含有多个特征是 会很有用。然后我们数据类型 换成 np.float32。

# exit(0)

##

# 现在我们使用KMeans函数。在之前我们应先置好终止条件。我的终止条件是算法执10次代或者精确度epsilon=1.0。

# Define criteria = ( type, max_iter = 10 , epsilon = 1.0 )
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# Set flags (Just to avoid line break in the code)

flags = cv2.KMEANS_RANDOM_CENTERS
# Apply KMeans
compactness, labels, centers = cv2.kmeans(z, 2, None, criteria, 10, flags)


# 返回值有紧密度compactness,标志和中心。在本例中我的到的中心是60和207。标志的数目与测数据的多少是相同的每个数据会标上01等。取决与它们的中心是什么。

A = z[labels == 0]
B = z[labels == 1]

# 现在我们可以根据它们的标志将把数据分两组。
# 现在将A组数用红色示
# 将B组数据用蓝色示,重心用黄色示。
# Now plot 'A' in red, 'B' in blue, 'centers' in yellow
plt.hist(A, 256, [0, 256], color='r')
plt.hist(B, 256, [0, 256], color='b')
plt.hist(centers, 32, [0, 256], color='y')
plt.show()

48.2.2-含有多个特征的数据.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午9:01
# @Author  : play4fun
# @File    : 48.2.2-含有多个特征的数据.py
# @Software: PyCharm

"""
48.2.2-含有多个特征的数据.py:
身高
体重

"""

# 在前 的 T 恤例子中我们只考 了   现在我们也把体 考  去 也 就是两个特征。
# 在前一节我们的数据是一个单列向 。每一个特征 排列成一列 每一  对应一个测 样本。
# 在本例中我们的测 数据 应 50x2 的向  其中包含 50 个人的  和 体 。第一列对应与   第二列对应与体 。第一 包含两个元素 第一个 是第一个人的   第二个是第一个人的体 。剩下的 对应与其他人的   和体 。

import numpy as np
import cv2
from matplotlib import pyplot as plt

X = np.random.randint(25, 50, (25, 2))
Y = np.random.randint(60, 85, (25, 2))
Z = np.vstack((X, Y))

# convert to np.float32
Z = np.float32(Z)
# define criteria and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
ret, label, center = cv2.kmeans(Z, 2, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)

# Now separate the data, Note the flatten()
A = Z[label.ravel() == 0]
B = Z[label.ravel() == 1]

# Plot the data
plt.scatter(A[:, 0], A[:, 1])
plt.scatter(B[:, 0], B[:, 1], c='r')
plt.scatter(center[:, 0], center[:, 1], s=80, c='y', marker='s')
plt.xlabel('Height'), plt.ylabel('Weight')
plt.show()

48.2.3_颜色量化.py

# -*- coding: utf-8 -*-
# @Time    : 2017/2/24 下午3:17
# @Author  : play4fun
# @File    : 48.2.3_颜色量化.py
# @Software: PyCharm

"""
48.2.3_颜色量化.py:
"""

# 颜色量化就是减少图片中颜色数目的一个过程。为什么 减少图片中的  色呢 减少内存消耗 有些 备的 源有  只能显示很少的 色。在 种情 况下就     色 化。我们使用 K 值聚类的方法来   色 化。
# 没有什么新的知   介绍了。现在有 3 个特征 R G B。所以我们   把图片数据变形成 Mx3 M 是图片中像素点的数目 的向 。聚类完成后  我们用聚类中心值替换与其同组的像素值  样结果图片就只含有指定数目的  色了。下 是代码
# -*- coding: utf-8 -*-

import numpy as np
import cv2

img = cv2.imread('../data/home.jpg')
# img = cv2.imread('../data/opencv_logo.png')
Z = img.reshape((-1, 3))
# convert to np.float32
Z = np.float32(Z)


# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# K = 8
# K = 3
K = 14
ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)


# Now convert back into uint8, and make original image
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))

cv2.imshow('res2', res2)
cv2.waitKey(0)
cv2.destroyAllWindows()

48.2.3_颜色量化2.py

# -*- coding: utf-8 -*-
# @Time    : 2017/2/24 下午3:17
# @Author  : play4fun
# @File    : 48.2.3_颜色量化.py
# @Software: PyCharm

"""
48.2.3_颜色量化.py:
"""

#  色 化就是减少图片中 色数目的一个 程。为什么 减少图片中的  色呢 减少内存消耗 有些 备的 源有  只能显示很少的 色。在 种情 况下就     色 化。我们使用 K 值聚类的方法来   色 化。
# 没有什么新的知   介绍了。现在有 3 个特征 R G B。所以我们   把图片数据变形成 Mx3 M 是图片中像素点的数目 的向 。聚类完成后  我们用聚类中心值替换与其同组的像素值  样结果图片就只含有指定数目的  色了。下 是代码
# -*- coding: utf-8 -*-

import numpy as np
import cv2

img = cv2.imread('../data/home.jpg')
# img = cv2.imread('../data/opencv_logo.png')
Z = img.reshape((-1, 3))
# convert to np.float32
Z = np.float32(Z)


# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 8
# K = 3
# K = 14
ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)

#分离颜色
for y in range(len(center)):
    a1 = []
    for i,x in enumerate(label.ravel()):
        if x==y:
            a1.append(list(Z[i]))
        else:
            a1.append([0,0,0])
    a2=np.array(a1)
    a3=a2.reshape((img.shape))
    cv2.imshow('res2'+str(y), a3)

#最大的色块



# # Now convert back into uint8, and make original image
# center = np.uint8(center)
# res = center[label.flatten()]
# res2 = res.reshape((img.shape))

# cv2.imshow('res2', res2)
# cv2.imshow('res2', a3)
cv2.waitKey(0)
cv2.destroyAllWindows()

ch49-计算摄影学-图像去噪

1-fastNlMeansDenoisingColored.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午9:56
# @Author  : play4fun
# @File    : 1-fastNlMeansDenoisingColored.py
# @Software: PyCharm

"""
1-fastNlMeansDenoisingColored.py:
"""

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('die.png')
img = cv2.cvtColor(img, code=cv2.COLOR_BGR2RGB)

dst = cv2.fastNlMeansDenoisingColored(img, None, 10, 10, 7, 21)
# dst2=cv2.cvtColor(dst,code=cv2.COLOR_BGR2RGB)

plt.subplot(121), plt.imshow(img)
plt.subplot(122), plt.imshow(dst)
# plt.subplot(122), plt.imshow(dst2)
plt.show()

2-fastNlMeansDenoisingMulti.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午9:57
# @Author  : play4fun
# @File    : 2-fastNlMeansDenoisingMulti.py
# @Software: PyCharm

"""
2-fastNlMeansDenoisingMulti.py:
"""

import numpy as np
import cv2
from matplotlib import pyplot as plt

cap = cv2.VideoCapture('../data/vtest.avi')
# create a list of first 5 frames
img = [cap.read()[1] for i in range(5)]
# convert all to grayscale
gray = [cv2.cvtColor(i, cv2.COLOR_BGR2GRAY) for i in img]
# convert all to float64
gray = [np.float64(i) for i in gray]


# create a noise of variance 25
noise = np.random.randn(*gray[1].shape) * 10
# Add this noise to images
noisy = [i + noise for i in gray]
# Convert back to uint8
noisy = [np.uint8(np.clip(i, 0, 255)) for i in noisy]

# Denoise 3rd frame considering all the 5 frames
dst = cv2.fastNlMeansDenoisingMulti(noisy, 2, 5, None, 4, 7, 35)


plt.subplot(131), plt.imshow(gray[2], 'gray')
plt.subplot(132), plt.imshow(noisy[2], 'gray')
plt.subplot(133), plt.imshow(dst, 'gray')
plt.show()

ch50-2-HDR-HighDynamicRange

HDR.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午11:43
# @Author  : play4fun
# @File    : HDR.py
# @Software: PyCharm

"""
HDR.py:
http://docs.opencv.org/3.2.0/d2/df0/tutorial_py_hdr.html

了解如何从曝光序列生成和显示HDR图像。
使用曝光融合合并曝光序列。

高动态范围成像(HDRI或HDR)是一种用于成像和摄影的技术,可以重现比标准数字成像或摄影技术更大的动态光度范围。虽然人眼可以调整到广泛的光线条件,但大多数成像设备每通道使用8位,因此我们仅限于256级。当我们拍摄现实世界的场景时,明亮的地区可能曝光过度,而黑暗的区域可能曝光不足,所以我们无法使用单次曝光拍摄所有细节。HDR图像与每个通道使用超过8位(通常为32位浮点值)的图像一起使用,允许更宽的动态范围。

有不同的获取HDR图像的方法,但最常见的是使用不同曝光值拍摄的场景的照片。要组合这些曝光,了解您的相机的响应功能是有用的,并且有算法来估计它。合并HDR图像后,必须将其转换回8位才能在通常的显示屏上进行查看。这个过程叫做tonemapping。当场景或相机的对象在拍摄之间移动时,会出现附加的复杂性,因为具有不同曝光的图像应该被注册和对齐。

在本教程中,我们展示了两种算法(Debvec,Robertson)从曝光序列生成和显示HDR图像,并展示了一种称为曝光融合(Mertens)的替代方法,它产生低动态范围图像,不需要曝光时间数据。此外,我们估计对于许多计算机视觉算法具有重要价值的相机响应函数(CRF)。HDR管道的每一步都可以使用不同的算法和参数来实现,因此请参考参考手册来查看。



"""

import cv2
import numpy as np

# 第一阶段只是将所有图像加载到列表中。此外,我们将需要常规HDR算法的曝光时间。注意数据类型,因为图像应为1通道或3通道8位(np.uint8),曝光时间需要为float32,以秒为单位。
# Loading exposure images into a list
img_fn = ["1tl.jpg", "2tr.jpg", "3bl.jpg", "4br.jpg"]
img_list = [cv2.imread(fn) for fn in img_fn]
exposure_times = np.array([15.0, 2.5, 0.25, 0.0333], dtype=np.float32)

# Merge exposures to HDR image
# 在这个阶段,我们将曝光序列合并成一个HDR图像,显示了我们在OpenCV中的两种可能性。第一种方法是Debvec,第二种是Robertson。请注意,HDR图像的类型为float32,而不是uint8,因为它包含所有曝光图像的完整动态范围。

merge_debvec = cv2.createMergeDebevec()
hdr_debvec = merge_debvec.process(img_list, times=exposure_times.copy())
merge_robertson = cv2.createMergeRobertson()
hdr_robertson = merge_robertson.process(img_list, times=exposure_times.copy())

# Tonemap HDR image
# 我们将32位浮点HDR数据映射到范围[0..1]。实际上,在某些情况下,值可能大于1或低于0,所以注意我们以后不得不剪切数据,以避免溢出。
tonemap1 = cv2.createTonemapDurand(gamma=2.2)
res_debvec = tonemap1.process(hdr_debvec.copy())
tonemap2 = cv2.createTonemapDurand(gamma=1.3)
res_robertson = tonemap2.process(hdr_robertson.copy())

# Exposure fusion using Mertens
# 这里我们展示了一种可以合并曝光图像的替代算法,我们不需要曝光时间。我们也不需要使用任何tonemap算法,因为Mertens算法已经给出了[0..1]范围内的结果。
merge_mertens = cv2.createMergeMertens()
res_mertens = merge_mertens.process(img_list)

# Convert datatype to 8-bit and save
# 为了保存或显示结果,我们需要将数据转换为[0..255]范围内的8位整数。
res_debvec_8bit = np.clip(res_debvec * 255, 0, 255).astype('uint8')
res_robertson_8bit = np.clip(res_robertson * 255, 0, 255).astype('uint8')
res_mertens_8bit = np.clip(res_mertens * 255, 0, 255).astype('uint8')

cv2.imwrite("ldr_debvec.jpg", res_debvec_8bit)
cv2.imwrite("ldr_robertson.jpg", res_robertson_8bit)
cv2.imwrite("fusion_mertens.jpg", res_mertens_8bit)

exit(0)

# Estimate camera response function (CRF)
# 相机响应功能(CRF)给出了场景辐射度与测量强度值之间的连接。如果在一些计算机视觉算法中非常重要,包括HDR算法,CRF。这里我们估计反相机响应函数并将其用于HDR合并。
cal_debvec = cv2.createCalibrateDebevec()
crf_debvec = cal_debvec.process(img_list, times=exposure_times)
hdr_debvec = merge_debvec.process(img_list, times=exposure_times.copy(), response=crf_debvec.copy())
cal_robertson = cv2.createCalibrateRobertson()
crf_robertson = cal_robertson.process(img_list, times=exposure_times)
hdr_robertson = merge_robertson.process(img_list, times=exposure_times.copy(), response=crf_robertson.copy())

ch50-图像修补

inpaint.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/13 下午10:33
# @Author  : play4fun
# @File    : inpaint.py
# @Software: PyCharm

"""
inpaint.py:
算法
1.基于快速行进算法cv2.INPAINT_TELEA
2.基于流体动力学并使用了偏微分方程。基本原理是启发式的    cv2.INPAINT_NS
"""

import numpy as np
import cv2

img = cv2.imread('../data/messi_2.jpg')
mask = cv2.imread('../data/mask2.png', 0)
cv2.imshow('img', img)
cv2.imshow('mask', mask)

dst = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA)
cv2.imshow('INPAINT_TELEA', dst)

dst2 = cv2.inpaint(img, mask, 3, cv2.INPAINT_NS)
cv2.imshow('INPAINT_NS', dst2)

cv2.waitKey(0)
cv2.destroyAllWindows()

ch51-对象检测-使用Haar分类器进行面部检测

51.CascadeClassifier级联分类器.py

# -*- coding: utf-8 -*-

'''
以 Haar 特征分类器为基础的面部检测技术
将面部检测扩展到眼部检测等。

以 Haar 特征分类器为基础的对 检测技术是一种 常有效的对 检测 技术 2001 年 Paul_Viola 和 Michael_Jones 提出 。它是基于机器学习的    使用大 的正 样本图像 练得到一个 cascade_function 最后再用它 来做对 检测。
现在我们来学习  检测。开始时 算法  大 的正样本图像   图 像 和 样本图像 不含  的图像 来 练分类器。我们  从其中提取特 征。下图中的 Haar 特征会 使用。它们就像我们的卷积核。每一个特征是一 个值  个值等于 色矩形中的像素值之后减去白色矩形中的像素值之和。

 那么我们怎样从超过160000+ 个特征中 出最好的特征呢 ?
 使用 Adaboost。

OpenCV 自带了训练器和检测器。如果你想自己训练一个分类器来检测 汽车飞机等的
可以使用 OpenCV 构建。
Cascade Classifier Training :http://docs.opencv.org/2.4/doc/user_guide/ug_traincascade.html


'''

import numpy as np
import cv2

# 运行之前,检查cascade文件路径是否在你的电脑上
face_cascade = cv2.CascadeClassifier('/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('/usr/local/share/OpenCV/haarcascades/haarcascade_eye.xml')

# img = cv2.imread('../data/sachin.jpg')
# img = cv2.imread('../data/kongjie_hezhao.jpg')
img = cv2.imread('../data/airline-stewardess-bikini.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# cv2.imshow('gray', gray)


# Detects objects of different sizes in the input image.
# The detected objects are returned as a list of rectangles.
# cv2.CascadeClassifier.detectMultiScale(image, scaleFactor, minNeighbors, flags, minSize, maxSize)
# scaleFactor – Parameter specifying how much the image size is reduced at each image
# scale.
# minNeighbors – Parameter specifying how many neighbors each candidate rectangle should
# have to retain it.
# minSize – Minimum possible object size. Objects smaller than that are ignored.
# maxSize – Maximum possible object size. Objects larger than that are ignored.
# faces = face_cascade.detectMultiScale(gray, 1.3, 5)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE)#改进
print("Detected ", len(faces), " face")

for (x, y, w, h) in faces:
    img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
    roi_gray = gray[y:y + h, x:x + w]
    roi_color = img[y:y + h, x:x + w]

    eyes = eye_cascade.detectMultiScale(roi_gray)
    for (ex, ey, ew, eh) in eyes:
        cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

行人检测

Pedestrian_Detection_video.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/23 下午4:14
# @Author  : play4fun
# @File    : Pedestrian_Detection_video.py
# @Software: PyCharm

"""
Pedestrian_Detection_video.py:检测视频里的行人

视频网站
https://v.qq.com/x/page/t0501y6jtfi.html

"""

# import the necessary packages
from __future__ import print_function
from imutils.object_detection import non_max_suppression
from imutils import paths
import numpy as np
import argparse
import imutils
import cv2
import time

# construct the argument parse and parse the arguments
# ap = argparse.ArgumentParser()
# ap.add_argument("-i", "--images", required=True, help="path to images directory")
# args = vars(ap.parse_args())

# initialize the HOG descriptor/person detector
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

#
cap = cv2.VideoCapture('videos/礼让斑马线!齐齐哈尔城市文明的伤!.mp4')
# cap = cv2.VideoCapture('../../data/TownCentreXVID.mp4')

fps = cap.get(cv2.CAP_PROP_FPS)  # 25.0
print("Frames per second using video.get(cv2.CAP_PROP_FPS) : {0}".format(fps))
num_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
print('共有', num_frames, '帧')  # 共有 2499.0 帧

frame_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
frame_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
print('高:', frame_height, '宽:', frame_width)  # 高: 480.0 宽: 640.0
# exit(0)


# 跳过多少帧
skips = 20

# loop over the image paths
# for imagePath in paths.list_images(args["images"]):
while cap.isOpened():

    # load the image and resize it to (1) reduce detection time
    # and (2) improve detection accuracy
    # image = cv2.imread(imagePath)

    ret, frame = cap.read()
    image = frame

    #
    current = cap.get(cv2.CAP_PROP_POS_FRAMES)
    if current % skips != 0:
        continue

    image = imutils.resize(image, width=min(400, image.shape[1]))
    orig = image.copy()

    # detect people in the image
    (rects, weights) = hog.detectMultiScale(image, winStride=(4, 4),
                                            padding=(8, 8), scale=1.05)

    # draw the original bounding boxes
    for (x, y, w, h) in rects:
        cv2.rectangle(orig, (x, y), (x + w, y + h), (0, 0, 255), 2)

    # apply non-maxima suppression to the bounding boxes using a
    # fairly large overlap threshold to try to maintain overlapping
    # boxes that are still people
    rects = np.array([[x, y, x + w, y + h] for (x, y, w, h) in rects])
    pick = non_max_suppression(rects, probs=None, overlapThresh=0.65)

    # draw the final bounding boxes
    for (xA, yA, xB, yB) in pick:
        cv2.rectangle(image, (xA, yA), (xB, yB), (0, 255, 0), 2)

    # show some information on the number of bounding boxes
    # filename = imagePath[imagePath.rfind("/") + 1:]
    # print("[INFO] {}: {} original boxes, {} after suppression".format(
    print("[INFO] {} original boxes, {} after suppression".format(len(rects), len(pick)))

    # show the output images
    cv2.imshow("Before NMS", orig)
    cv2.imshow("After NMS", image)
    cv2.moveWindow("After NMS", y=0, x=400)

    key = cv2.waitKey(delay=1)
    if key == ord("q"):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

Pedestrian_Detection1.py

# -*- coding: utf-8 -*-
# @Time    : 2017/7/23 下午3:55
# @Author  : play4fun
# @File    : Pedestrian_Detection1.py
# @Software: PyCharm

"""
Pedestrian_Detection1.py:

网址
http://www.pyimagesearch.com/2015/11/09/pedestrian-detection-opencv/

运行
python Pedestrian_Detection1.py --images images
"""

# import the necessary packages
from __future__ import print_function
from imutils.object_detection import non_max_suppression
from imutils import paths
import numpy as np
import argparse
import imutils
import cv2

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--images", required=True, help="path to images directory")
args = vars(ap.parse_args())

# initialize the HOG descriptor/person detector
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

# loop over the image paths
for imagePath in paths.list_images(args["images"]):
    # load the image and resize it to (1) reduce detection time
    # and (2) improve detection accuracy
    image = cv2.imread(imagePath)
    image = imutils.resize(image, width=min(400, image.shape[1]))
    orig = image.copy()

    # detect people in the image
    (rects, weights) = hog.detectMultiScale(image, winStride=(4, 4),
                                            padding=(8, 8), scale=1.05)

    # draw the original bounding boxes
    for (x, y, w, h) in rects:
        cv2.rectangle(orig, (x, y), (x + w, y + h), (0, 0, 255), 2)

    # apply non-maxima suppression to the bounding boxes using a
    # fairly large overlap threshold to try to maintain overlapping
    # boxes that are still people
    rects = np.array([[x, y, x + w, y + h] for (x, y, w, h) in rects])
    pick = non_max_suppression(rects, probs=None, overlapThresh=0.65)

    # draw the final bounding boxes
    for (xA, yA, xB, yB) in pick:
        cv2.rectangle(image, (xA, yA), (xB, yB), (0, 255, 0), 2)

    # show some information on the number of bounding boxes
    filename = imagePath[imagePath.rfind("/") + 1:]
    print("[INFO] {}: {} original boxes, {} after suppression".format(
        filename, len(rects), len(pick)))

    # show the output images
    cv2.imshow("Before NMS", orig)
    cv2.moveWindow('Before NMS', x=0, y=0)
    cv2.imshow("After NMS", image)
    cv2.moveWindow('After NMS', x=orig.shape[1], y=0)
    k=cv2.waitKey(0)
    if k==ord('q'):
        break

ch52-Python_C++_binding_in_OpenCV

你可能感兴趣的:(opencv,opencv)