38、OpenCV之C++教程

发布时间:2023-03-17 12:00

一、OpenCV的下载与安装

38、OpenCV之C++教程_第1张图片

38、OpenCV之C++教程_第2张图片

38、OpenCV之C++教程_第3张图片

下载完成后会得到一个 opencv-3.4.15-vc14_vc15.exe 文件,点击运行后会生成一个文件夹。
此文件夹为下一步工程创建使用,文件夹可移动、复制和重命名,这里命名如下:

二、VS2019创建OpenCV基础工程

2.1、创建VS工程

38、OpenCV之C++教程_第4张图片

38、OpenCV之C++教程_第5张图片

38、OpenCV之C++教程_第6张图片

2.2、附加包含目录

38、OpenCV之C++教程_第7张图片

附加包含目录:$(SolutionDir)\OpenCV3.4.15\opencv\build\include

38、OpenCV之C++教程_第8张图片

附加lib库目录:$(SolutionDir)\OpenCV3.4.15\opencv\build\x64\vc15\lib

38、OpenCV之C++教程_第9张图片

 附加dll库目录:PATH=$(SolutionDir)\OpenCV3.4.15\opencv\build\x64\vc15\bin;%PATH%

38、OpenCV之C++教程_第10张图片

 2.3、附加依赖项

Debug模式下的依赖项:opencv_world3415d.lib

38、OpenCV之C++教程_第11张图片

 Release模式下的依赖项:opencv_world3415.lib

38、OpenCV之C++教程_第12张图片

至此配置完成,开启你的OpenCV之旅吧!

三、OpenCV基本操作教程

3.1、打印版本

#include 
#include 
int main(int argc, char** argv)
{
    std::cout << "OpenCV_Version: " << CV_VERSION << std::endl;
    cv::waitKey(0);
    return 0;
}

3.2、显示图像

//示例一:以原格式读取并显示图像
#include 
#include 
using namespace cv;
int main(int argc, char** argv)
{
    //读取图片
    Mat img = imread("../images/liyifeng.jpg", cv::IMREAD_UNCHANGED);//以原图格式读取
    if (img.empty()) {
        std::cout << "加载图片失败" << std::endl;
    }
    else {
        imshow("窗口1", img);  //在窗口1中显示图片img(窗口大小不能调整)
        imshow("窗口2", img);  //在窗口2中显示图片img(窗口大小不能调整)
    }
    waitKey(0);            //显示图片的窗口停顿
    //waitKey(2000);       //显示图片的窗口停顿2000ms
    //destroyAllWindows(); //销毁所有的窗口
    return 0;
}
//示例二:以灰度格式读取并显示图片
#include 
#include 
using namespace cv;
int main(int argc, char** argv)
{
    Mat img = imread("../images/liyifeng.jpg", IMREAD_GRAYSCALE);//以灰度格式读取图片
    if (img.empty()) {
        std::cout << "加载图片失败" << std::endl;
    }
    else {
        namedWindow("hello world", cv::WINDOW_FREERATIO); //创建一个名为hello world的窗口
        imshow("hello world", img); //在hello world的窗口上显示图片img
    }
    waitKey(0);          //显示图片的窗口停顿
    //destroyAllWindows(); //销毁所有的窗口
    return 0;
}
//WINDOW_FREERATIO:图片布满窗口,窗口大小也可以拉伸调整

3.3、格式转换

#include 
#include 
using namespace cv;
int main(int argc, char** argv)
{
    //读取图片
    Mat img_source = imread("../images/liyifeng.jpg", IMREAD_UNCHANGED);//以原图格式读取
    if (img_source.empty()) {
        std::cout << "加载图片失败" << std::endl;
    }
    else {
        Mat img_hsv, img_gray;
        cvtColor(img_source, img_hsv, COLOR_BGR2HSV); //img_source转HSV格式,结果存到img_hsv中
        cvtColor(img_source, img_gray, COLOR_BGR2GRAY); //img_source转灰度格式,结果存到img_gray中
        imshow("img_hsv - HSV空间", img_hsv);
        imshow("img_gray - 灰度空间", img_gray);
    }
    waitKey(0);          //显示图片的窗口停顿
    //destroyAllWindows(); //销毁所有的窗口
    return 0;
}
//COLOR_BGR2GRAY = 6 : BGR到灰度
//COLOR_GRAY2BGR = 8 : 灰度到BGR
//COLOR_BGR2HSV = 40 : BGR到HSV
//COLOR_HSV2BGR = 54 : HSV到BGR

3.4、保存图像

#include 
#include 
using namespace cv;
int main(int argc, char** argv)
{
    //读取图片
    Mat img_source = imread("../images/liyifeng.jpg", IMREAD_UNCHANGED);//以原图格式读取
    if (img_source.empty()) {
        std::cout << "加载图片失败" << std::endl;
    }
    else {
        if (imwrite("../images/liyifeng_save.jpg", img_source)){  //注意.jpg是有损压缩,.png是无损压缩
            std::cout << "图片保存成功" << std::endl;
        }
        else {
            std::cout << "图片保存失败" << std::endl;
        }
    }
    waitKey(0);          //显示图片的窗口停顿
    //destroyAllWindows(); //销毁所有的窗口
    return 0;
}

3.5、翻转图像

3.6、几何绘制

3.7、文字绘制

3.8、Mat对象的创建

// 示例一:创建
#include 
#include 
using namespace cv;
int main(int argc, char** argv)
{
    Mat img = Mat::zeros(Size(4, 4), CV_8UC3); //CV_8UC3:8位、unsigned char、三通道
    namedWindow("imgx 窗口", WINDOW_FREERATIO); //创建一个名为"imgx 窗口"的窗口
    //显示一
    std::cout << "显示一:显示图像的参数" << "\r\n";
    std::cout << img << "\r\n";                          //打印矩阵
    std::cout << "dims:" << img.dims << "\r\n";          //打印维度
    std::cout << "width:" << img.cols << "\r\n";         //打印宽度
    std::cout << "height:" << img.rows << "\r\n";        //打印高度
    std::cout << "size:" << img.size << "\r\n";          //打印尺寸
    std::cout << "total:" << img.total() << "\r\n";      //打印像素总数
    std::cout << "elemSize" << img.elemSize() << "\r\n"; //矩阵每个像素所占字节数(一个像素三个数组元素)
    std::cout << "channel:" << img.channels() << "\r\n"; //矩阵每个像素所用通道数(一个像素三个数组元素)
    std::cout << "type:" << cv::typeToString(img.type()) << "\r\n";    //矩阵每个像素的数据类型
    std::cout << "depth:" << cv::depthToString(img.depth()) << "\r\n"; //矩阵每个像素的通道的数据类型
    //显示二
    std::cout << "显示二:图像的赋值操作" << "\r\n";
    Mat imgx;
    img.copyTo(imgx);        //把img拷贝一份给imgx
    imgx = Scalar(255, 0, 0);  //imgx的每个像素点各通道都赋值成(0,0,255)
    std::cout << imgx << "\r\n";                          //打印矩阵
    imshow("imgx 窗口", imgx);
    //显示三(C++知识)
    //Mat imgy = imgx;          //浅拷贝
    //imgx.copyTo(imgy);        //条件深拷贝
    //Mat imgy = imgx.clone();  //完全深拷贝
    waitKey(0);          //显示图片的窗口停顿
    //destroyAllWindows(); //销毁所有的窗口
    return 0;
}

3.9、Mat对象的读写 

//示例: 遍历与读写
#include 
#include 
using namespace cv;
int main(int argc, char** argv)
{
    Mat image = Mat::zeros(Size(2, 2), CV_8UC3); //CV_8UC3:8位三通道   
    int width = image.cols; //列
    int height = image.rows; //行
    int channel = image.channels(); //通道数
    //一、修改图像各点像素值
    switch (channel) {
    case 1: {
        image.at(0, 0) = 0x00; image.at(0, 1) = 0xFF;
        image.at(1, 0) = 0xFF; image.at(1, 1) = 0x00;
        break;
    }
    case 3: { //彩色图像
        image.at(0, 0) = { 0,0,255 }; image.at(0, 1) = { 0,255,0 }; // 00 01
        image.at(1, 0) = { 255,0,0 }; image.at(1, 1) = { 0,0,0 };   // 10 11
        //image.at(row, col)[0] = 0;   //写、(单独写一个像素B通道)
        //image.at(row, col)[1] = 255; //写、(单独写一个像素G通道)
        //image.at(row, col)[2] = 0;   //写、(单独写一个像素R通道)
        break;
    }
    default: {break; }
    }
    //二、遍历图像读取像素值
    for (int row = 0; row < height; row++) {
        for (int col = 0; col < width; col++) {
            switch (channel) {
            case 1: {//灰度图像(row=行,col=列)
                int pv = image.at(row, col); //读
                std::cout << "row,col=" << pv << "\r\n";
                break;
            }
            case 3: { //彩色图像
                Vec3b bgr = image.at(row, col);//读
                std::cout << "row,col=" << bgr << "\r\n";
                break;
            }
            default: {break; }
            }
        }
    }
    cv::namedWindow("imgx 窗口", WINDOW_FREERATIO); //创建一个名为"imgx 窗口1"的窗口
    cv::imshow("imgx 窗口", image);
    cv::waitKey(0); //显示图片的窗口停顿
    //cv::destroyAllWindows(); //销毁所有的窗口
    return 0;
}

Python版本参考

opencv3.4.1.15之后的版本,在某些识别算法上商业化了,所以建议使用3.4.1.15版本的,但是由于conda和pip中已经搜不到opencv3.4.1.15的版本了,这里提供pip的离线安装包下载:
文件下载地址:https://download.csdn.net/download/BaoTTing/85133357
离线安装命令:pip install folder:xxx.whl
(说明:资源已经限制在5积分下载,不会动态调整)

P1.01、几何绘制

//示例、几何绘制
# 这是一个示例 Python 脚本。
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    img = np.zeros((512, 512, 3), np.uint8)
    cv.line(img, (0, 0), (511, 511), (255, 0, 0), 5)
    cv.circle(img, (256, 256), 60, (0, 0, 255), -1)
    cv.rectangle(img, (100, 100), (400, 400), (0, 255, 0), 5)
    cv.putText(img, "hello", (100, 150), cv.FONT_HERSHEY_COMPLEX, 5, (255, 255, 255), 3)
    plt.imshow(img[:, :, ::-1])
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.02、像素修改 

# 示例、像素修改和格式获取
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    img = cv.imread("ant.jpg", cv.IMREAD_UNCHANGED)
    px = img[50, 50]  # 获取某个像素点的值
    print("px = ", px)  # 打印px的值
    blue = img[50, 50, 0]  # 仅获取蓝色通道的强度值
    print("blue = ", blue)  # 打印blue的值
    print("img.shape = ", img.shape)  # 打印像素尺寸
    print("img.size = ", img.size)  # 打印有
    print("img.dtype = ", img.dtype)  # 打印通道的数据类型
    img[100, 100] = [255, 255, 255]  # 修改某个位置的像素值
    img[100, 101] = [255, 255, 255]  # 修改某个位置的像素值
    img[100, 102] = [255, 255, 255]  # 修改某个位置的像素值
    img[100, 103] = [255, 255, 255]  # 修改某个位置的像素值
    img[100, 104] = [255, 255, 255]  # 修改某个位置的像素值
    plt.imshow(img[:, :, ::-1])  # BGR转RGB
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.03、边界填充

# 示例、边界填充
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    # 1、读取图像
    img = cv.imread("ant.jpg", cv.IMREAD_UNCHANGED)
    # 2、边界填充尺寸
    top_size, bottom_size, left_size, right_size = (50, 50, 50, 50)
    # 3、边界填充
    replicate = cv.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv.BORDER_REPLICATE)  # 边缘复制
    reflect1 = cv.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv.BORDER_REFLECT)  # 反射法1
    reflect2 = cv.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv.BORDER_REFLECT_101)  # 反射法2
    wrap = cv.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv.BORDER_WRAP)  # 外包装法
    constant = cv.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv.BORDER_CONSTANT, value=0)  # 常量填充
    # 5、使用matplot进行图像显示
    fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(10, 8), dpi=100)
    axes[0, 0].imshow(img[:, :, ::-1])
    axes[0, 0].set_title("原图")
    axes[0, 1].imshow(replicate[:, :, ::-1])
    axes[0, 1].set_title("边缘复制")
    axes[0, 2].imshow(reflect1[:, :, ::-1])
    axes[0, 2].set_title("反射法1")

    axes[1, 0].imshow(reflect2[:, :, ::-1])
    axes[1, 0].set_title("反射法2")
    axes[1, 1].imshow(wrap[:, :, ::-1])
    axes[1, 1].set_title("外包装法")
    axes[1, 2].imshow(constant[:, :, ::-1])
    axes[1, 2].set_title("常量填充")
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.04、通道分割

# 示例、图像的分割与合并
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    img = cv.imread("ant.jpg", cv.IMREAD_UNCHANGED)
    b, g, r = cv.split(img)  # 通道拆分
    img = cv.merge((b, g, r))  # 通道合并
    plt.subplot(1, 2, 1)
    plt.imshow(b)
    img = img[:, :, ::-1]  # BGR转RGB
    plt.subplot(1, 2, 2)
    plt.imshow(img)  # 对图像进行处理
    plt.show()  # 对图像进行显示
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

 P1.05、格式转换

# 示例、图像格式的转换、色彩空间
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    input_img = cv.imread("ant.jpg", cv.IMREAD_UNCHANGED)

    img_hsv = cv.cvtColor(input_img, cv.COLOR_BGR2HSV)
    img_gray = cv.cvtColor(input_img, cv.COLOR_BGR2GRAY)

    plt.subplot(1, 2, 1)
    plt.imshow(img_hsv)
    plt.subplot(1, 2, 2)
    plt.imshow(img_gray, cmap=plt.cm.gray)
    plt.show()  # 对图像进行显示
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

 P1.06、图像加法

# 示例、图像的加法
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    # 1、数值加法
    # numpy的加法是饱和取模运算、超过边界取模值
    # OpenCV的加法是饱和取边界操作、超过边界取边界值
    x = np.uint8([250])
    y = np.uint8([10])
    print("numpy add=", x+y)            # numpy-> 250 + 10 = 260%256 = 4
    print("OpenCV add=", cv.add(x, y))  # OpenCV-> 250 + 10 = 255
    # 对比两种加法,可见OpenCV的加法更常用(减法也是cv比较常用)
    # 2、图像加法
    img1 = cv.imread("view.jpg")
    img2 = cv.imread("rain.jpg")
    npadd_img = img1 + img2
    cvadd_img = cv.add(img1, img2)
    # 3、图像显示
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
    axes[0].imshow(npadd_img[:, :, ::-1])
    axes[0].set_title("np add")
    axes[1].imshow(cvadd_img[:, :, ::-1])
    axes[1].set_title("cv add")
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.07、图像混合 

# 示例、图像的混合
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    # 图像的混合也是加法,不同的是两幅图像的权重不同,给人一种混合或者透明的感觉。
    # 即 g(x) = (1-a)*f0(x)+a*f1(x),改变a的值可以实现非常炫酷的混合。
    # cv2.addWeight()可以按公式: dst = a*img1+b*img2+c进行混合(取c=0即可)。
    img1 = cv.imread("view.jpg")
    img2 = cv.imread("rain.jpg")
    img_blend_1 = cv.addWeighted(img1, 0.7, img2, 0.3, 0)
    img_blend_2 = cv.addWeighted(img1, 0.3, img2, 0.7, 0)
    # 图像显示
    fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
    axes[0].imshow(img_blend_1[:, :, ::-1])
    axes[0].set_title("a=0.7,b=0.3,c=0")
    axes[1].imshow(img_blend_2[:, :, ::-1])
    axes[1].set_title("a=0.3,b=0.7,c=0")
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

 P1.08、图像缩放 

# 示例、图像缩放
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 图像缩放:对图像的大小进行调整,即图像的放大或者缩小
# 函数:cv2.resize(src,desize,fx=0,fy=0,interpolation=cv2.INTER_LINEAR)
# src:输入图像
# dsize:绝对尺寸,直接指定调整后图像大小
# fx,fy:相对尺寸,将desize设置为None,然后将fx,fy设置为比例因子即可
# interpolation:插值方法
#   cv2.INTER_LINEAR:双线性插值法
#   cv2.INTER_NEAREST:最近邻插值
#   cv2.INTER_AREA:像素区域重采样
#   cv2.INTER_CUBIC:双三次插值法
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    img_src = cv.imread("kids.jpg")
    rows, cols = img_src.shape[:2]
    print("img_src_size:", img_src.shape)
    # 绝对尺寸
    img_abs = cv.resize(img_src, (2 * cols, 2 * rows), interpolation=cv.INTER_CUBIC)
    print("img_abs_size:", img_abs.shape)
    # 相对尺寸
    img_com = cv.resize(img_src, None, fx=0.5, fy=0.5)
    print("img_com_size:", img_com.shape)
    # 1、使用cv进行图像显示
    cv.imshow("img_src", img_src)
    cv.imshow("img_abs", img_abs)
    cv.imshow("img_com", img_com)
    cv.waitKey(0)
    # 2、使用matplot进行图像显示
    # fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
    # axes[0].imshow(img_src[:, :, ::-1])
    # axes[0].set_title("原始图片(放大)")
    # axes[1].imshow(img_abs[:, :, ::-1])
    # axes[1].set_title("绝对尺寸(放大)")
    # axes[2].imshow(img_com[:, :, ::-1])
    # axes[2].set_title("相对尺寸(缩小)")
    # plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.09、图像平移

# 示例、图像平移
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 图像平移:将图像按照指定的方向和距离,移动相应的位置
# 函数:cv2.wrapAffine(img, M, dsize)
# img:输入图像
# M:2*3的移动矩阵,对于(x, y)处的像素点, 要把它移动到(x+tx,y+ty处),使用如下矩阵
#   M = [ 1 0 tx]
#       [ 0 1 ty]
# 注意:将M设置为np.float32类型的Numpy数组
# desize: 输出图像的大小,它是(width,height)的形式,即(列数,行数)
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    img_src = cv.imread("kids.jpg")
    rows, cols = img_src.shape[:2]
    print("img_src_size:", img_src.shape)
    # 图像平移
    M = np.float32([[1, 0, 100], [0, 1, 50]])
    img_trans1 = cv.warpAffine(img_src, M, (cols, rows))
    img_trans2 = cv.warpAffine(img_src, M, (2*cols, 2*rows))
    print("img_trans1_size:", img_trans1.shape)
    print("img_trans2_size:", img_trans1.shape)
    # 1、使用cv进行图像显示
    cv.imshow("img_src", img_src)
    cv.imshow("img_trans1", img_trans1)
    cv.imshow("img_trans2", img_trans2)
    cv.waitKey(0)
    # 2、使用matplot进行图像显示
    # fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
    # axes[0].imshow(img_src[:, :, ::-1])
    # axes[0].set_title("原始图片")
    # axes[1].imshow(img_trans1[:, :, ::-1])
    # axes[1].set_title("平移图片1")
    # axes[2].imshow(img_trans2[:, :, ::-1])
    # axes[2].set_title("平移图片2")
    # plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.10、图像旋转

# 示例、图像旋转
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# API函数1:cv2.getRotationMatrix2D(center,angle,scale) 获取旋转矩阵
#   center:旋转中心
#   angle:旋转角度
#   scale:缩放比例
# API函数2:cv2.wrapAffine() 用法见示例八
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    img_src = cv.imread("kids.jpg")
    rows, cols = img_src.shape[:2]
    print("img_src_size:", img_src.shape)
    # 图像旋转
    M = cv.getRotationMatrix2D((cols/2, rows/2), 45, 1.0)  # 获取旋转矩阵
    img_rotate = cv.warpAffine(img_src, M, (cols, rows))
    print("img_rotate_size:", img_rotate.shape)
    # 使用cv进行图像显示
    cv.imshow("img_src", img_src)
    cv.imshow("img_rotate", img_rotate)
    cv.waitKey(0)
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.11、仿射变换

# 示例、仿射变换
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 仿射变换涉及图像的形状位置角度的变化,是深度学习与预处理中常用到的功能,仿射变换主要是对图像的缩放、旋转、翻转、平移等操作的组合
# 在OpenCV中,仿射变换是一个2*3的矩阵 M=[A B] <其实就是建立一种映射关系A->B>
# API函数1:cv2.getAffineTransform(src, dst) 获取仿射变换矩阵
# src:原坐标
# dst:映射坐标
# API函数2:cv2.wrapAffine() 用法见示例八
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    # 1、图像读取
    img_src = cv.imread("kids.jpg")
    print("img_src_size:", img_src.shape)
    # 2、仿射变换
    rows, cols = img_src.shape[:2]
    # 2.1、创建变换矩阵
    pst1 = np.float32([[50, 50], [200, 50], [50, 200]])
    pst2 = np.float32([[100, 100], [200, 50], [100, 250]])
    M = cv.getAffineTransform(pst1, pst2)
    # 2.2、进行图像的仿射变换
    img_dst = cv.warpAffine(img_src, M, (cols, rows))
    print("img_rotate_size:", img_dst.shape)
    # 1、使用cv进行图像显示
    cv.imshow("img_src", img_src)
    cv.imshow("img_rotate", img_dst)
    cv.waitKey(0)
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.12、透射变换

# 示例、透射变换
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 透射变换是视角变化的结果,是指利用透视中心、像点、目标点、三点共线的条件,按照透视变换定律使得透
# 视面(承影面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光束,仍能保持承影面上投影几何不变的变换。
# API函数1:cv2.getPerspectiveTransform(pts1, pts2)
# API函数2:cv2.wrapPerspective() 用法见示例八
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    # 1、图像读取
    img_src = cv.imread("kids.jpg")
    print("img_src_size:", img_src.shape)
    # 2、投射变换
    rows, cols = img_src.shape[:2]
    # 2.1、创建变换矩阵
    pst1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])
    pst2 = np.float32([[100, 145], [300, 100], [80, 290], [310, 300]])
    M = cv.getPerspectiveTransform(pst1, pst2)
    # 2.2、进行图像的仿射变换
    img_dst = cv.warpPerspective(img_src, M, (cols, rows))
    print("img_rotate_size:", img_dst.shape)
    # 1、使用cv进行图像显示
    cv.imshow("img_src", img_src)
    cv.imshow("img_rotate", img_dst)
    cv.waitKey(0)
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.13、图像金字塔

# 示例、图像金字塔
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 图像金字塔是图像多尺寸表达,类似OpenGL中的mip纹理,以多种分辨率来解释图像的有效表达
# 图像金字塔用于机器视觉和图像压缩,一幅图像金字塔是一系列以金字塔形状排列的分辨率逐渐降低
# 且来源于同一张原始图的图像集合,其通过梯次向下采样获得,直到达到某个终止条件才停止采样
# 金字塔的底部是待处理的图像高分辨率表示,而顶部是低分辨率的近似,图像越高,分辨率越低
# API函数1、cv.pyrUp(img)   #对图像进行上采样,分辨率增大
# API函数2、cv.pyrDown(img) #对图像进行下采样,分辨率降低
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    # 1、图像读取
    img_src = cv.imread("kids.jpg")
    print("img_src_size:", img_src.shape)
    # 2、图像金字塔
    rows, cols = img_src.shape[:2]
    # 2.1、图片上采样
    img_Up = cv.pyrUp(img_src)
    print("img_Up_size:", img_Up.shape)
    # 2.2、图像下采样
    img_Down = cv.pyrDown(img_src)
    print("img_Down_size:", img_Down.shape)
    # 1、使用cv进行图像显示
    cv.imshow("img_Up", img_Up)
    cv.imshow("img_src", img_src)
    cv.imshow("img_Down", img_Down)
    cv.waitKey(0)
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.14、腐蚀与膨胀

# 示例、腐蚀与膨胀
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 图像邻接:每个像素周围有8个邻接像素,常见的邻接关系有4邻接、8邻接、D邻接
# 图像的连通:1、两个像素是否相邻。2、两个像素的像素值是否满足特定的相似准则
#   4连通:对于具有值V的像素p和q,如果q在p的4邻接中,则称这两个像素为4连通
#   8连通:对于具有值V的像素p和q,如果q在p的8邻接中,则称这两个像素为8连通
#   m连通:对于具有值V的像素p和q,如果q在p的4邻接或D邻接中,且p的4邻接和q的4邻接不相交(交集中没有值为V的像素),则称这两个像素为m连通
# 腐蚀:局部最小值,(消除物体的边界点,使目标缩小,可用于消除小于结构元素的噪声点)
# 膨胀:局部最大值,(将与物体接触的所有背景点合并到物体中,使目标增大,可填补目标中的孔洞)
# API函数1:cv2.erode(img, kernel, iterations)
# API函数2:cv2.dilate(img, kernel, iterations)
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    # 1、图像读取
    img_src = cv.imread("letter.png")
    print("img_src_size:", img_src.shape)
    # 2、创建核结构
    kernel = np.ones((5, 5), np.uint8)
    # 3、图像腐蚀
    img_erode = cv.erode(img_src, kernel)
    # 4、图片膨胀
    img_dilate = cv.dilate(img_src, kernel)
    # 5、使用matplot进行图像显示
    fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
    axes[0].imshow(img_src[:, :, ::-1])
    axes[0].set_title("img_src")
    axes[1].imshow(img_erode[:, :, ::-1])
    axes[1].set_title("img_erode")
    axes[2].imshow(img_dilate[:, :, ::-1])
    axes[2].set_title("img_dilate")
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.15、开、闭操作

# 示例、开、闭操作
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 开操作是先腐蚀后膨胀,作用是分离物体,消除小区域,消除噪点,去除小的干扰块。
# 闭操作是先膨胀后腐蚀,作用是消除闭合物体里面的孔洞,可以填充闭合区域
# API函数:cv2.morphologyEx(img, op, kernel)
# op=cv2.MORPH_OPEN:开操作
# op=cv2.MORPH_CLOSE:闭操作
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    # 1、图像读取
    img_src1 = cv.imread("letteropen.png")
    img_src2 = cv.imread("letterclose.png")
    print("img_src1_size:", img_src1.shape)
    print("img_src2_size:", img_src2.shape)
    # 2、创建核结构
    kernel = np.ones((10, 10), np.uint8)
    # 3、图像开操作
    img_src1_open = cv.morphologyEx(img_src1, cv.MORPH_OPEN, kernel)
    # 4、图片闭操作
    img_src2_close = cv.morphologyEx(img_src2, cv.MORPH_CLOSE, kernel)
    # 5、使用matplot进行图像显示
    fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8), dpi=100)
    axes[0, 0].imshow(img_src1[:, :, ::-1])
    axes[0, 0].set_title("原图1")
    axes[0, 1].imshow(img_src1_open[:, :, ::-1])
    axes[0, 1].set_title("原图1开操作")
    axes[1, 0].imshow(img_src2[:, :, ::-1])
    axes[1, 0].set_title("原图2")
    axes[1, 1].imshow(img_src2_close[:, :, ::-1])
    axes[1, 1].set_title("原图2闭操作")
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.16、礼帽与黑帽

# 示例、礼帽与黑帽操作
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 礼帽操作:原图像与开运算的结果差(dst=src-open(src,element))
#   开运算的结果是放大了裂缝或局部低亮度区域,因此,从原图中减去开运算的图,得到的效果突出了比原图轮廓周围区域更明亮的区域,且这一操作和选择核的大小相关。
#   礼貌运算用来分离比临近点亮一些的斑块,当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用顶帽运算进行背景提取。
# 黑帽操作:闭运算与原图像的结果差(dst=close(src,element)-src)
#   黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关。黑帽运算用来分离比邻近点暗一些的斑块。
# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    # 1、读取图像
    img_src1 = cv.imread("letteropen.png")
    img_src2 = cv.imread("letterclose.png")
    print("img_src1_size:", img_src1.shape)
    print("img_src2_size:", img_src2.shape)
    # 2、创建核结构
    kernel = np.ones((10, 10), np.uint8)
    # 3、图像开操作
    img_src1_tophat = cv.morphologyEx(img_src1, cv.MORPH_TOPHAT, kernel)
    # 4、图片闭操作
    img_src2_blackhat = cv.morphologyEx(img_src2, cv.MORPH_BLACKHAT, kernel)
    # 5、使用matplot进行图像显示
    fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8), dpi=100)
    axes[0, 0].imshow(img_src1[:, :, ::-1])
    axes[0, 0].set_title("原图1")
    axes[0, 1].imshow(img_src1_tophat[:, :, ::-1])
    axes[0, 1].set_title("原图1礼帽运算")
    axes[1, 0].imshow(img_src2[:, :, ::-1])
    axes[1, 0].set_title("原图2")
    axes[1, 1].imshow(img_src2_blackhat[:, :, ::-1])
    axes[1, 1].set_title("原图2黑帽操作")
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.17、图像的平滑

# 示例、图像的平滑
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 均值滤波:
#   API:cv2.blur(src, ksize, anchor, borderType)
# 高斯滤波:
#   API:cv2.GaussianBlur(src,ksize,sigmaX,sigmay,borderType)
# 中值滤波:
#   API:cv2.medianBlur(src, ksize)
# 双边滤波:
#   API:cv.bilateralFilter(src, d, sigmaColor,sigmaSpace, dst, borderType)
if __name__ == '__main__':
    # 1、读取图像
    img_sp_src = cv.imread("dogsp.jpeg")     # 带椒盐噪声原图
    img_ga_src = cv.imread("dogGauss.jpeg")  # 带高斯噪声原图
    print("img_sp_size:", img_sp_src.shape)
    print("img_ga_size:", img_ga_src.shape)
    # 2、均值滤波
    img_sp_dst1 = cv.blur(img_sp_src, (5, 5))  # 原图1的均值滤波
    img_sp_dst2 = cv.blur(img_ga_src, (5, 5))  # 原图2的均值滤波
    img_ga_dst = cv.GaussianBlur(img_ga_src, (3, 3), 1)  # 高斯噪声(适合高斯噪声)
    img_me_dst = cv.medianBlur(img_sp_src, 5)  # 中值滤波(适合椒盐噪声)
    # 5、使用matplot进行图像显示
    fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(10, 8), dpi=100)
    axes[0, 0].imshow(img_sp_src[:, :, ::-1])
    axes[0, 0].set_title("带椒盐噪声原图1")
    axes[0, 1].imshow(img_sp_dst1[:, :, ::-1])
    axes[0, 1].set_title("原图1的均值滤波")
    axes[0, 2].imshow(img_me_dst[:, :, ::-1])
    axes[0, 2].set_title("原图1的中值滤波")

    axes[1, 0].imshow(img_ga_src[:, :, ::-1])
    axes[1, 0].set_title("带高斯噪声原图2")
    axes[1, 1].imshow(img_sp_dst2[:, :, ::-1])
    axes[1, 1].set_title("原图2均值滤波")
    axes[1, 2].imshow(img_ga_dst[:, :, ::-1])
    axes[1, 2].set_title("原图2高斯滤波")
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.18、直方图均衡

# 示例、直方图均衡化
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 使用OpenCV中的方法统计直方图,并使用matplotlib将其绘制出来
# 掩膜的作用是提取感兴趣的区域(蒙版->掩膜)
# 直方图均衡化能提升对比度,用于处理曝光过度或曝光不足的图片
# 统计直方图的API:cv2.calcHist(images,channels,mask,histSize,ranges[,hist[,accumulate]])
if __name__ == '__main__':
    # 1、读取图像
    img_src = cv.imread("cat.jpeg", cv.IMREAD_GRAYSCALE)  # 以灰度的格式读取图片
    # 2、统计完整直方图(不带掩膜)
    img_histr = cv.calcHist([img_src], [0], None, [256], [0, 256])
    # 3、统计带掩膜的直方图
    # 3.1、创建蒙版
    mask = np.zeros(img_src.shape[:2], np.uint8)
    mask[400:650, 200:500] = 1
    # 3.2、创建掩膜
    masked_img = cv.bitwise_and(img_src, img_src, mask=mask)  # 蒙版与原图相与
    # 3.3、原图带掩膜的直方图
    mask_histr = cv.calcHist([img_src], [0], mask, [256], [0, 256])
    # 4、对原图进行直方图均衡化
    img_dst = cv.equalizeHist(img_src)
    # 5、使用matplot进行图像显示
    fig, axes = plt.subplots(nrows=3, ncols=2, figsize=(10, 6), dpi=100)
    axes[0, 0].imshow(img_src, cmap=plt.cm.gray)
    axes[0, 0].set_title("原图")

    axes[0, 1].plot(img_histr)
    axes[0, 1].set_title("原图直方图(不带掩膜)")
    axes[0, 1].grid()  # 添加网格

    axes[1, 0].imshow(mask, cmap=plt.cm.gray)
    axes[1, 0].set_title("蒙版数据")

    axes[1, 1].imshow(masked_img, cmap=plt.cm.gray)
    axes[1, 1].set_title("掩膜数据")

    axes[2, 0].plot(mask_histr)
    axes[2, 0].set_title("带掩膜的直方图")
    axes[2, 0].grid()  # 添加网格

    axes[2, 1].imshow(img_dst, cmap=plt.cm.gray)
    axes[2, 1].set_title("直方图均衡化结果")
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.19、自适应均衡

# 示例、自适应均衡化
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 直方图均衡化是对图像整体的均衡,改变全局对比度,虽说能增强背景细节,但某些区域对比度好的区域在直方图均衡化后效果会变差
# cv.createCLAHE(clipLimit, tileGridSize)
#   clipLimit: 对比度限制,默认是40
#   tileGridSize: 分块的大小,默认为8*88∗8
if __name__ == '__main__':
    # 1、读取图像
    img_src = cv.imread("cat.jpeg", cv.IMREAD_GRAYSCALE)  # 以灰度的格式读取图片
    # 2、统计原图直方图
    img_src_histr = cv.calcHist([img_src], [0], None, [256], [0, 256])
    # 3、创建一个自适应均衡化的对象
    clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
    # 4、自适应均衡化
    img_dst = clahe.apply(img_src)
    # 5、统计均衡化后的直方图
    img_dst_histr = cv.calcHist([img_dst], [0], None, [256], [0, 256])
    # 6、使用matplot进行图像显示
    fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 6), dpi=100)
    axes[0, 0].imshow(img_src, cmap=plt.cm.gray)
    axes[0, 0].set_title("原图")

    axes[0, 1].plot(img_src_histr)
    axes[0, 1].set_title("原图直方图")
    axes[0, 1].grid()  # 添加网格

    axes[1, 0].imshow(img_dst, cmap=plt.cm.gray)
    axes[1, 0].set_title("自适应均衡化")

    axes[1, 1].plot(img_dst_histr)
    axes[1, 1].set_title("均衡化后的直方图")
    axes[1, 1].grid()  # 添加网格
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.20、边缘检测之Sobel

# 示例、边缘检测之Sobel
# Sobel算子:用于边缘检测,简单效率高,虽然不如Canny检测准确,但实际很多场合,Sobel算子是首选(Sobel算子基于一阶导数)
#      [ -1 +0 +1 ]         [ -1 -2 -1 ]
# Gx = [ -2 +0 +2 ]    Gy = [ +0 +0 +0 ]    Gx用于检测水平变化,Gy用于检测垂直变化
#      [ -1 +0 +1 ]         [ +1 +2 +1 ]
# Scharr算子:当内核大小为3时,以上Sobel可能产生比较明显误差,我们使用Scharr算子替代来解决这个问题(Scharr仅适用于内核大小为3)
#      [ -3  +0 +3  ]         [ -3 -10 -3 ]
# Gx = [ -10 +0 +10 ]    Gy = [ +0  +0 +0 ]    Gx用于检测水平变化,Gy用于检测垂直变化
#      [ -3  +0 +3  ]         [ +3 +10 +3 ]
# API函数 cv2.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)
# (src:传入的图像)(ddepth:图像的深度)(dx和dy:指求导的阶数,0表示这个方向上没有求导,取值为0、1)
# (ksize:是Sobel算子的大小,即卷积核的大小,必须为奇数1、3、5、7,默认为3.注意:如果ksize=-1,就演变成为3x3的Scharr算子)
# (scale:缩放导数的比例常数,默认情况为没有伸缩系数)(borderType:图像边界的模式,默认值为cv2.BORDER_DEFAULT)
# ->Sobel函数求完导数后会有负值,还有会大于255的值。而原图像是uint8,即8位无符号数,所以Sobel建立的图像位数不够,会有截断。
# ->因此要使用16位有符号的数据类型,即cv2.CV_16S。处理完图像后,再使用cv2.convertScaleAbs()函数将其转回原来的uint8格式,否则图像无法显示。
# ->Sobel算子是在两个方向计算的,最后还需要用cv2.addWeighted()函数将其组合起来
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 主函数
if __name__ == '__main__':
    # 1、读取图像
    img_src = cv.imread("horse.jpg", cv.IMREAD_GRAYSCALE)  # 以灰度的格式读取图片
    # 2、计算Sobel卷积结果
    sobel_x = cv.Sobel(img_src, cv.CV_16S, 1, 0)  # Scharr: cv.Sobel(img_src, cv.CV_16S, 1, 0, ksize=-1)
    sobel_y = cv.Sobel(img_src, cv.CV_16S, 0, 1)  # Scharr: cv.Sobel(img_src, cv.CV_16S, 0, 1, ksize=-1)
    # 3、将数据进行转换
    scaleAbs_x = cv.convertScaleAbs(sobel_x)
    scaleAbs_y = cv.convertScaleAbs(sobel_y)
    # 4、结果合成
    result = cv.addWeighted(scaleAbs_x, 0.5, scaleAbs_y, 0.5, 0)
    # 5、使用matplot进行图像显示
    plt.subplot(1, 2, 1), plt.imshow(img_src, cmap=plt.cm.gray), plt.title("原图")
    plt.subplot(1, 2, 2), plt.imshow(result, cmap=plt.cm.gray), plt.title("Sobel滤波后结果")
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.21、边缘检测之Laplacian

# 示例、边缘检测之Laplacian(拉普拉斯)
# Laplacian算子:Laplacian是利用二阶导数来检测边缘
#          [ +0 +1 +0 ]
# kernel = [ +1 -4 +1 ]
#          [ +0 +1 +0 ]
# API函数:cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
# Src:需要处理的图像.
# Ddepth:图像的深度,-1表示采用的是原图像相同的深度,目标图像的深度必须大于等于原图像的深度.
# ksize:算子的大小,即卷积核的大小,必须为1,3,5,7.
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 主函数
if __name__ == '__main__':
    # 1、读取图像
    img_src = cv.imread("horse.jpg", cv.IMREAD_GRAYSCALE)  # 以灰度的格式读取图片
    # 2、laplacian
    lap_dst = cv.Laplacian(img_src, cv.CV_16S)
    img_dst = cv.convertScaleAbs(lap_dst)
    # 3、使用matplot进行图像显示
    plt.subplot(1, 2, 1), plt.imshow(img_src, cmap=plt.cm.gray), plt.title("原图")
    plt.subplot(1, 2, 2), plt.imshow(img_dst, cmap=plt.cm.gray), plt.title("Laplacian滤波后结果")
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

P1.22、边缘检测之Canny

# 示例、边缘检测Canny
# Canny边缘检测算法是由4步构成,分别介绍如下:
# 第一步:噪声去除(由于边缘检测很容易受到噪声的影响,所以首先使用$5*5$高斯滤波器去除噪声)
# 第二步:计算图像梯度(对平滑后的图像使用Sobel算子计算水平方向和竖直方向的一阶导数(Gx和Gy),梯度方向分为四类:垂直,水平,和两个对角线方向)
# 第三步:非极大值抑制(在获得梯度的方向和大小之后,对整幅图像进行扫描,去除那些非边界上的点。对每一个像素进行检查,看这个点的梯度是不是周围具有相同梯度方向的点中最大的)
# 第四步:滞后阈值(现在要确定真正的边界。我们设置两个阈值:minVal和maxVal。当图像的灰度梯度高于maxVal时被认为是真的边界,
#       低于minVal的边界会被抛弃。如果介于两者之间的话,就要看这个点是否与某个被确定为真正的边界点相连,如果是就认为它也是边界点,如果不是就抛弃)
# API函数:cv2.Canny(image, threshold1, threshold2)
#       image:灰度图。
#       threshold1: minval,较小的阈值将间断的边缘连接起来。
#       threshold2: maxval,较大的阈值检测图像中明显的边缘。
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 添加plot的中文支持
font = {'family': 'SimHei', 'weight': 'bold', 'size': 12}
plt.rc("font", **font)
# 主函数
if __name__ == '__main__':
    # 1、读取图像
    img_src = cv.imread("horse.jpg", cv.IMREAD_GRAYSCALE)  # 以灰度的格式读取图片
    # 2、Canny检测
    img_dst = cv.Canny(img_src, 0, 100)
    # 3、使用matplot进行图像显示
    plt.subplot(1, 2, 1), plt.imshow(img_src, cmap=plt.cm.gray), plt.title("原图")
    plt.subplot(1, 2, 2), plt.imshow(img_dst, cmap=plt.cm.gray), plt.title("Canny后的结果")
    plt.show()
# 访问 https://www.jetbrains.com/help/pycharm/ 获取 PyCharm 帮助

 常见算子的比较与总结:

38、OpenCV之C++教程_第13张图片

P1.23、模板匹配<重点>

所谓的模板匹配,就是在给定的图片中查找和模板最相似的区域,该算法的输入包括模板和图片,整个任务的思路就是按照滑窗的思路不断的移动模板图片,计算其与图像中对应区域的匹配度,最终将匹配度最高的区域选择为最终的结果。

实现流程:

  • 准备两幅图像:

    1.原图像(I):在这幅图中,找到与模板相匹配的区域

    2.模板(T):与原图像进行比对的图像块

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号