OpenCV快速入门——基础知识(二)

OpenCV入门基础知识

        • 1. 模板匹配
        • 2. 梯度算法
        • 3. 阈值算法
        • 4. 形态学操作
        • 5. 摄像头的读取

1. 模板匹配

本次以扑克牌上的菱形为例:
OpenCV快速入门——基础知识(二)_第1张图片

import cv2
import numpy as np

image = cv2.imread("poker.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #转化为灰度图
#选取图像的一个区域作为匹配模板,如下是一个菱形的区域
template = gray[75:105, 235:265]
#第三个参数是将图片标准化,防止外界环境影响。计算匹配度,计算结果更准确
match = cv2.matchTemplate(gray, template, cv2.TM_CCOEFF_NORMED)
locations = np.where(match >= 0.9) #找出匹配系数大于0.9的匹配点
#求模板图片的长和宽,方便作图
w, h = template.shape[0:2]
#循环遍历每一个匹配点
for p in zip(*locations[::-1]):
    x1, y1 = p[0], p[1]
    x2, y2 = x1 + w, y1 + h
    # 在原始图像上画框
    cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)

cv2.imshow("image", image)
cv2.waitKey()

OpenCV快速入门——基础知识(二)_第2张图片

这里仅把图像大小相等的框了出来,要想把不同大小的匹配出来,可以设置图像大小来匹配。

2. 梯度算法

图像的梯度就是图像的明暗变化
取水平和垂直方向上的明暗变化,再求出两个变化的平方和就得到了梯度

import cv2

gray = cv2.imread("opencv_logo.jpg", cv2.IMREAD_GRAYSCALE) #转化为灰度图
#拉普拉斯算子
laplacian = cv2.Laplacian(gray, cv2.CV_64F)
#Canny边缘检测
canny = cv2.Canny(gray, 100, 200) #设置梯度区间(100,200)
#像素梯度大于200,可以确定是一个边缘,小于100是非边缘,100-200待定
cv2.imshow("gray", gray)
cv2.imshow("laplacian", laplacian)
cv2.imshow("canny", canny)

cv2.waitKey()

Laplace算子的函数原型

dst = cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])

前两个是必须的参数:
第一个参数是需要处理的图像;
第二个参数是图像的深度,-1表示采用的是与原图像相同的深度。目标图像的深度必须大于等于原图像的深度
结果:
OpenCV快速入门——基础知识(二)_第3张图片

两个算法的优缺点:
    Laplacian:对图像中的阶跃性边缘点定位准确,对噪声非常敏感,丢失一部分边缘的方向信息,造成一些不连续的检测边缘
    Canny:不容易受噪声影响,能检测到真正的弱边缘,在edge函数中,最有效的边缘检测方法。使用两种不同的阈值分别检测边缘强度和若边缘且当若边缘与强边缘相连时,才将若边缘包含在输出图像中,更容易检测出若边缘。

3. 阈值算法

OpenCV快速入门——基础知识(二)_第4张图片

从给出的图片可知,光照分布不均,很难确定一个固定阈值把他分离出来
 两种方法:
1.手动设置阈值的方法

import cv2

gray = cv2.imread("bookpage.jpg", cv2.IMREAD_GRAYSCALE)
#阈值为10,最大灰度255
ret, binary = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)
cv2.imshow("gray", gray)
cv2.imshow("binary", binary)

cv2.waitKey()

结果后面展示。
2.自适应阈值:
把图片分成多个区域,对每个区域独立计算阈值
threshold函数使用一个阈值对图像进行二值化

import cv2

gray = cv2.imread("bookpage.jpg", cv2.IMREAD_GRAYSCALE)
ret, binary = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)
#
binary_adaptive=cv2.adaptiveThreshold(gray,255,
cv2.ADAPTIVE_THRESH_GASSIAN_C,cv2.THRESH_BINARY,115,1)
#  每个区域大小155个像素

ret1, binary_otsu = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
#常用的阈值算法,自动计算恰当的阈值,使得分离出的两个灰度分布差异最大化
cv2.imshow("gray", gray)
cv2.imshow("binary", binary)
cv2.imshow("adaptive", binary_adaptive)
cv2.imshow("otsu", binary_otsu)

cv2.waitKey()

cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)

 这个函数大致意思就是把图片每个像素点作为中心取N*N的区域,然后计算这个区域的阈值,来决定这个像素点变0还是变255
 src:需要进行二值化的一张灰度图像
 maxValue:满足条件的像素点需要设置的灰度值。(将要设置的灰度值)
 adaptiveMethod:自适应阈值算法。可选ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C
 thresholdType:opencv提供的二值化方法,只能THRESH_BINARY或者THRESH_BINARY_INV
 blockSize:要分成的区域大小,上面的N值,一般取奇数
 当blockSize越大,参与计算阈值的区域也越大,细节轮廓就变得越少,整体轮廓越粗越明显
 C:常数,每个区域计算出的阈值的基础上在减去这个常数作为这个区域的最终阈值,可以为负数

4. 形态学操作

形态学算法:腐蚀和膨胀
这一节操作要基于图像二值化

import cv2
import numpy as np

gray = cv2.imread("opencv_logo.jpg", cv2.IMREAD_GRAYSCALE)
#先做阈值处理,这里用反向阈值,因为图片背景是白色,想让他变成黑色
_, binary = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV)
kernel = np.ones((5, 5), np.uint8)
#腐蚀操作
erosion = cv2.erode(binary, kernel)
#膨胀操作
dilation = cv2.dilate(binary, kernel)

cv2.imshow("binary", binary)
cv2.imshow("erosion", erosion)
cv2.imshow("dilation", dilation)

cv2.waitKey()

OpenCV快速入门——基础知识(二)_第5张图片
腐蚀与膨胀对于清理图像边缘细节很有帮助
  交替使用腐蚀与膨胀能使我们更好的处理图片边缘部分。
如:
原图:
OpenCV快速入门——基础知识(二)_第6张图片

开运算是指先进行腐蚀操作,再进行膨胀操作

# 开运算:先腐蚀,再膨胀
import cv2
import numpy as np
img = cv2.imread('dige.png')

kernel = np.ones((5,5),np.uint8) 
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

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

OpenCV快速入门——基础知识(二)_第7张图片
闭运算:先膨胀,再腐蚀

# 闭:先膨胀,再腐蚀
img =cv2.imread('dige.png')

kernel = np.ones((5,5),np.uint8) 
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

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

OpenCV快速入门——基础知识(二)_第8张图片

5. 摄像头的读取

import cv2
#获取摄像头的指针
capture = cv2.VideoCapture(0)

while True:
    ret, frame = capture.read()
    cv2.imshow("camera", frame)
    key = cv2.waitKey(1)
    if key != -1:
        break

capture.release(

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