opencv十四天入门学习——task7

opencv十四天入门学习——task7

  • 前言
  • 1、像素重映射
  • 2、图像二值化
  • 3、全局与自适应二值化
    • 3.1 全局二值化
    • 3.2 自适应二值化
  • 4、实时人脸检测

前言

本次学习是系列教程的最后一个学习任务,十四天的学习也迎来尾声。本次学习内容主要有像素重映射,图像二值化,全局与自适应二值化,以及实时人脸检测。通过本次对opencv的初步系统学习,我了解并掌握了opencv的初级用法,为以后的学习奠定了基础。

1、像素重映射

把输入图像中各个像素按照一定的规则映射到另外一张图像的对应位置上去,形成一张新的图像。

像素重映射函数:

cv.remap(src, map1, map2, interpolation[, dst[, borderMode[, borderValue]]] ) -> dst
src表示图像
map1表示x,y方向映射规则,或者x方向映射
Map2如果map1表示x,y映射时为空,否则表示y
表示映射时候的像素插值方法 支持:INTER_NEAREST 、NTER_LINEAR 、NTER_CUBIC

实验代码:

import cv2 as cv
import numpy as np
def trackbar_callback(pos):
    print(pos)

image = cv.imread("apple.jpg")
cv.imshow("apple", image)
cv.namedWindow("remap-demo", cv.WINDOW_AUTOSIZE)
cv.createTrackbar("remap-type", "remap-demo", 0, 3, trackbar_callback)
h, w, c = image.shape
map_x = np.zeros((h, w), dtype=np.float32)
map_y = np.zeros((h, w), dtype=np.float32)
while True:
    pos = cv.getTrackbarPos("remap-type", "remap-demo")
    if pos == 0:
        for i in range(map_x.shape[0]):
            map_x[i, :] = [x for x in range(map_x.shape[1])]
        for j in range(map_y.shape[1]):
            map_y[:, j] = [map_y.shape[0] - y for y in range(map_y.shape[0])]
    elif pos == 1:
        for i in range(map_x.shape[0]):
            map_x[i, :] = [map_x.shape[1] - x for x in range(map_x.shape[1])]
        for j in range(map_y.shape[1]):
            map_y[:, j] = [y for y in range(map_y.shape[0])]
    elif pos == 2:
        for i in range(map_x.shape[0]):
            map_x[i, :] = [map_x.shape[1] - x for x in range(map_x.shape[1])]
        for j in range(map_y.shape[1]):
            map_y[:, j] = [map_y.shape[0] - y for y in range(map_y.shape[0])]
    elif pos == 3:
        for i in range(map_x.shape[0]):
            map_x[i, :] = [int(x/2) for x in range(map_x.shape[1])]
        for j in range(map_y.shape[1]):
            map_y[:, j] = [int(y/2) for y in range(map_y.shape[0])]
    dst = cv.remap(image, map_x, map_y, cv.INTER_LINEAR)
    cv.imshow("remap-demo", dst)
    c = cv.waitKey(100)
    if c == 27:
        break
cv.destroyAllWindows()

实验结果:

2、图像二值化

图像二值化就是只有两个像素值0和1,黑色表示背景,白色表示对象。图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。

实验代码:

import cv2 as cv
import numpy as np

image = cv.imread("apple.jpg")
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("gray", gray)
ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY)
cv.imshow("binary_hand", binary)
m = cv.mean(gray)[0]
ret1, binary1 = cv.threshold(gray, m, 255, cv.THRESH_BINARY)
cv.imshow("binary-mean", binary1)
cv.waitKey(0)
cv.destroyAllWindows()

实验效果:

3、全局与自适应二值化

3.1 全局二值化

(1)大津法

0~5六个灰度级别,根据直方图分布,以每个灰度等级分割直方图分布为两个部分,分别求取均值跟方差,最小化方差使得对应的灰度值为分割阈值。大津法是日本学者大津在1979年提出的方法,对单峰值或者比较平坦的灰度值有很好的效果,对双峰或者多峰的情况则较差。

(2)三角法

三角法是使用直方图数据,基于纯几何方法来寻找最佳阈值。它的成立条件是假设直方图最大波峰在靠近最亮的一侧,然后通过三角形求得最大直线距离,根据最大直线距离对应的直方图灰度等级即为分割阈值。

全局二值化函数:

cv.threshold( src, thresh, maxval, type[, dst]) -> retval, dst
type表示二值化,THRESH_BINARY | THRESH_OTSU、THRESH_BINARY | THRESH_TRIANGLE、THRESH_BINARY_INV | THRESH_OTSU表示不同的全局二值化方法

3.2 自适应二值化

非自适应的二值化就是一个阈值往往只对应一类图像,如果图像的光照变暗了,那个单阈值情况的二值化效果会大大的折扣。自适应二值化其实就是一种根据图片的灰度直方图,得到一个适合本图像的二值化阈值。opencv提供的是基于阈值的自适应二值化方法,有均值和高斯两种可以选择,具体原理是模糊图像D (可以为均值模糊/高斯模糊),原图S,偏置常量C,T = S –D > -C ? 255 : 0。

自适应二值化函数:

cv.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst] ) ->dst
cv.ADAPTIVE_THRESH_MEAN_C、cv.ADAPTIVE_THRESH_GAUSSIAN_C
blockSize必须为奇数
C表示要减去的权重,可以是正数,负数,0;用于表达在计算过程中容忍程度;

实验代码:

import cv2 as cv
import numpy as np

image = cv.imread("apple.jpg")
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("gray", gray)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
cv.imshow("binary_OTSU", binary)

ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE)
cv.imshow("binary_TRIANGLE", binary)

binary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
cv.imshow("binary_GAUSSIAN", binary)

cv.waitKey(0)
cv.destroyAllWindows()

实验结果:

4、实时人脸检测

OpenCV3.3之前基于HAAR/LBP级联检测进行人脸检测,随着深度学习的广泛应用发展,从OpenCV3.3版本后开始引入深度学习人脸检测,基于深度学习的人脸检测方法全方面优秀于传统算法。

OpenCV中的深度学习模块(DNN)只提供了推理功能,不涉及模型的训练,支持多种深度学习框架,比如TensorFlow,Caffe,Torch和Darknet。支持后台硬件加速机制 CPU/GPU等,支持多种任务(分类、检测、分割、风格迁移、场景文字检测等)。

DNN相关函数:

读取模型:readNetFromTensorflow
转换为blob对象:blobFromImage
设置输入:setInput
推理预测:forward

实验代码:

import cv2 as cv
import numpy as np

model_bin = "opencv_face_detector_uint8.pb"
config_text = "opencv_face_detector.pbtxt";
font = cv.FONT_HERSHEY_SIMPLEX
font_scale = 0.5
thickness = 1

net = cv.dnn.readNetFromTensorflow(model_bin, config=config_text)
capture = cv.VideoCapture("01.mp4")

while True:
    e1 = cv.getTickCount()
    ret, frame = capture.read()
    frame = cv.flip(frame, 1)
    if ret is not True:
        break
    h, w, c = frame.shape
    blobImage = cv.dnn.blobFromImage(frame, 1.0, (300, 300), (104.0, 177.0, 12.0), False, False)
    net.setInput(blobImage)
    cvOut = net.forward()
    print(cvOut.shape)

    t, _ = net.getPerfProfile()
    label = 'Inference time: %.2f ms' % (t * 1000.0 / cv.getTickFrequency())

    for detection in cvOut[0, 0, :, :]:
        score = float(detection[2])
        objIndex = int(detection[1])
        if score > 0.5:
            left = detection[3]*w
            top = detection[4] * h
            right = detection[5] * w
            bottom = detection[6] * h
            cv.rectangle(frame, (int(left), int(top)), (int(right), int(bottom)), (255, 0, 0), thickness=2)
            label_txt = "score:%.2f"%score
            (fw, uph), dh = cv.getTextSize(label_txt, font, font_scale, thickness)
            cv.rectangle(frame, (int(left), int(top) - uph - dh), (int(left) + fw, int(top)), (255, 255, 255), -1, 8)
            cv.putText(frame, label_txt, (int(left), int(top) - dh), font, font_scale, (255, 0, 255), thickness)

    e2 = cv.getTickCount()
    fps = cv.getTickFrequency() / (e2 - e1)
    cv.putText(frame, label + (" FPS: %.2f"%fps), (10, 50), cv.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 2)
    cv.imshow('face-detection-demo', frame)
    c = cv.waitKey(1)
    if c == 27:
        break;
cv.waitKey(0)
cv.destroyAllWindows()

实验结果:
opencv十四天入门学习——task7_第1张图片

你可能感兴趣的:(opencv十四天入门学习笔记,opencv,学习,计算机视觉)