OpenCV从入门到精通:安装、配置、依赖、基本语法与常用方法详解

OpenCV从入门到精通:安装、配置、依赖、基本语法与常用方法详解

摘要本文旨在为计算机视觉初学者提供一份详尽的OpenCV入门指南。从OpenCV的安装配置、依赖项安装,到基本语法和常用方法的解析,我们力求以通俗易懂的方式,配合丰富的代码示例,帮助读者快速掌握OpenCV的核心概念和技术,并为后续深入学习打下坚实的基础。无论您是Python爱好者还是C++开发者,都能从中受益。最后,欢迎大家加我的微信一起交流学习!

引言大家好!作为一名默语博主,我深知初学者在接触新技术时常常会感到迷茫。计算机视觉领域更是如此,涉及众多的概念和工具。今天,我就为大家带来一篇保姆级的OpenCV入门教程。OpenCV(Open Source Computer Vision Library)作为一个功能强大的开源计算机视觉库,是进行图像处理、视频分析、物体识别等任务的利器。别看它名字听起来很“高大上”,其实只要跟着我的步骤一步步来,你会发现它并没有想象中那么难。让我们一起开启OpenCV的奇妙之旅吧!

2. 环境准备在开始安装OpenCV之前,我们需要确保你的计算机满足一些基本条件,并安装必要的依赖项。

2.1 系统需求OpenCV支持多种操作系统,包括Windows、Linux、macOS等。你需要一台能够运行这些操作系统的计算机。对于初学者来说,Windows或Linux都是不错的选择。

2.2 安装依赖根据你选择的编程语言(Python或C++),需要安装相应的依赖库。

2.2.1 Python 环境如果你选择使用Python进行OpenCV开发,你需要确保已经安装了Python环境。建议安装Python 3.7或更高版本。

可以通过以下方式检查Python是否已安装以及版本:

Bash

代码语言:javascript代码运行次数:0运行复制python --version或者Bash

代码语言:javascript代码运行次数:0运行复制python3 --version如果尚未安装,请前往Python官方网站下载并安装。

接下来,我们需要安装一些Python的常用库,这些库能够帮助我们更好地使用OpenCV:

NumPy: OpenCV中的图像数据是以NumPy数组的形式存储的,因此NumPy是OpenCV的基础。Matplotlib: 用于绘制图像和图表。可以使用pip(Python的包管理器)来安装这些库:

Bash

代码语言:javascript代码运行次数:0运行复制pip install numpy matplotlib如果你的Python环境配置了多个版本,可能需要使用pip3命令:

Bash

代码语言:javascript代码运行次数:0运行复制pip3 install numpy matplotlib2.2.2 C++ 环境如果你选择使用C++进行OpenCV开发,你需要一个C++编译器。常用的编译器有:

Windows: MinGW-w64(通常与CMake结合使用)、Visual StudioLinux: GCC、ClangmacOS: Xcode此外,我们还需要安装CMake,它是一个跨平台的构建系统,用于管理OpenCV的编译过程。

Windows: 可以从CMake官方网站下载安装程序。

Linux (Debian/Ubuntu): 可以使用apt命令安装:

Bash

代码语言:javascript代码运行次数:0运行复制sudo apt update

sudo apt install cmake cmake-curses-guiLinux (Fedora/CentOS): 可以使用yum或dnf命令安装:

Bash

代码语言:javascript代码运行次数:0运行复制sudo yum install cmake cmake-gui或者

Bash

代码语言:javascript代码运行次数:0运行复制sudo dnf install cmake cmake-guimacOS: 可以使用Homebrew安装:

Bash

代码语言:javascript代码运行次数:0运行复制brew install cmake3. OpenCV安装接下来,我们将分别介绍Python和C++环境下OpenCV的安装方法。

3.1 Python 环境安装在Python环境下安装OpenCV非常简单,可以直接使用pip命令:

Bash

代码语言:javascript代码运行次数:0运行复制pip install opencv-python或者,如果你需要包含contrib模块(包含一些额外的、可能不太稳定的功能),可以使用以下命令:

Bash

代码语言:javascript代码运行次数:0运行复制pip install opencv-contrib-python同样地,如果你的Python环境配置了多个版本,可能需要使用pip3命令:

Bash

代码语言:javascript代码运行次数:0运行复制pip3 install opencv-python安装完成后,你可以在Python交互式环境中导入cv2模块来验证是否安装成功:

Python

代码语言:javascript代码运行次数:0运行复制import cv2

print(cv2.__version__)如果能够成功打印出OpenCV的版本号,则说明安装成功。

3.2 C++ 环境安装(源码编译)在C++环境下安装OpenCV通常需要从源码进行编译,这可能稍微复杂一些,但能够提供更大的灵活性。

3.2.1 下载OpenCV源码你可以从OpenCV官方GitHub仓库下载最新或指定版本的源码。通常会下载一个zip或tar.gz压缩包。

3.2.2 下载OpenCV Contrib模块(可选)如果你需要使用contrib模块中的额外功能,也需要从OpenCV Contrib GitHub仓库下载源码。

3.2.3 创建构建目录在OpenCV源码目录下创建一个名为build的文件夹,用于存放编译生成的文件。

Bash

代码语言:javascript代码运行次数:0运行复制mkdir build

cd build3.2.4 使用CMake配置在build目录下运行CMake,配置编译选项。你需要指定OpenCV源码的路径以及contrib模块的路径(如果下载了的话)。

Bash

代码语言:javascript代码运行次数:0运行复制cmake -D CMAKE_BUILD_TYPE=Release \

-D CMAKE_INSTALL_PREFIX=/usr/local \

-D INSTALL_C_EXAMPLES=OFF \

-D INSTALL_PYTHON_EXAMPLES=OFF \

-D BUILD_EXAMPLES=OFF \

-D WITH_QT=OFF \

-D WITH_OPENGL=OFF \

-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules ../../opencv-D CMAKE_BUILD_TYPE=Release: 设置编译类型为Release,生成优化过的可执行文件。

-D CMAKE_INSTALL_PREFIX=/usr/local: 设置OpenCV的安装路径。你可以根据自己的需求修改。

-D INSTALL_C_EXAMPLES=OFF、

-D INSTALL_PYTHON_EXAMPLES=OFF、

-D BUILD_EXAMPLES=OFF 、 -D WITH_QT=OFF、

-D WITH_OPENGL=OFF

: 关闭一些不需要的选项,加快编译速度。

-D OPENCV_EXTRA_MODULES_PATH=…/…/opencv_contrib/modules 指定contrib模块的路径(相对于build目录)。你需要将其替换为你的实际路径。 …/…/opencv: 指定OpenCV源码的路径(相对于build目录)。同样需要根据你的实际路径进行调整。如果你没有下载contrib模块,可以省略-D OPENCV_EXTRA_MODULES_PATH=...这一行。

3.2.5 编译与安装配置完成后,使用make命令进行编译:

Bash

代码语言:javascript代码运行次数:0运行复制make -j4-j4表示使用4个线程进行编译,可以根据你的CPU核心数进行调整,加快编译速度。

编译完成后,使用以下命令进行安装:

Bash

代码语言:javascript代码运行次数:0运行复制sudo make install

sudo ldconfigsudo make install会将编译生成的文件安装到之前通过CMAKE_INSTALL_PREFIX指定的路径。sudo ldconfig会更新系统的动态链接库缓存,使得程序能够找到OpenCV的库文件。

4. OpenCV 配置安装完成后,我们还需要进行一些配置,以便在Python或C++项目中使用OpenCV。

4.1 Python 配置如果你是通过pip安装的OpenCV,通常情况下不需要进行额外的配置。Python会自动找到安装的cv2模块。

4.2 C++ 配置(CMake、IDE)如果你是通过源码编译安装的OpenCV,你需要告诉你的C++项目如何找到OpenCV的头文件和库文件。这通常通过CMake来实现。

4.2.1 使用CMakeLists.txt在你的C++项目的CMakeLists.txt文件中,你需要添加以下代码来查找OpenCV:

CMake

代码语言:javascript代码运行次数:0运行复制cmake_minimum_required(VERSION 3.10)

project(YourProjectName)

find_package(OpenCV REQUIRED)

include_directories(${OpenCV_INCLUDE_DIRS})

link_directories(${OpenCV_LIBS})

add_executable(YourExecutableName main.cpp)

target_link_libraries(YourExecutableName ${OpenCV_LIBS}) ind_package(OpenCV REQUIRED): 告诉CMake查找OpenCV。如果找不到,会报错。

include_directories(${OpenCV_INCLUDE_DIRS}) : 将OpenCV的头文件目录添加到包含路径中。

link_directories(${OpenCV_LIBS}) : 将OpenCV的库文件目录添加到链接路径中(通常不需要显式指定, target_link_libraries会自动处理)。

target_link_libraries(YourExecutableName ${OpenCV_LIBS}): 将OpenCV的库文件链接到你的可执行文件。

4.2.2 在IDE中配置如果你使用集成开发环境(IDE)如Visual Studio或CLion,你需要配置项目的构建设置,告诉IDE OpenCV的头文件和库文件在哪里。

Visual Studio:

你需要在项目属性中的“VC++目录”->“包含目录”中添加OpenCV的头文件路径,并在“VC++目录”->“库目录”中添加OpenCV的库文件路径。然后在“链接器”->“输入”->“附加依赖项”中添加你需要链接的OpenCV库文件(例如opencv_world4xxx.lib,具体名称取决于你的OpenCV版本)。

CLion: CLion通常会使用你的CMakeLists.txt文件进行配置,所以只需要确保你的CMakeLists.txt文件配置正确即可。

5. 基本语法现在我们已经安装并配置好了OpenCV,接下来让我们学习一些基本的语法。

5.1 包含头文件与命名空间5.1.1 C++在使用OpenCV的C++代码中,你需要包含相应的头文件。通常会包含opencv2/opencv.hpp这个头文件,它包含了OpenCV的大部分常用模块。

C++

代码语言:javascript代码运行次数:0运行复制#include

int main() {

// OpenCV 代码

return 0;

}为了方便使用OpenCV的函数和类,可以添加命名空间:

C++

代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

int main() {

// 使用 cv::Mat 等

Mat image;

return 0;

}5.1.2 Python在使用OpenCV的Python代码中,你需要导入cv2模块:

Python

代码语言:javascript代码运行次数:0运行复制import cv2

# OpenCV 代码5.2 Mat 类详解cv::Mat(C++)或 numpy.ndarray(Python)是OpenCV中用于表示图像的核心数据结构。它可以表示单通道或多通道的图像,每个通道可以存储不同数据类型的像素值。

C++: cv::Mat是一个类,提供了丰富的方法来操作图像数据。你可以指定图像的尺寸、数据类型和通道数来创建Mat对象。

C++

代码语言:javascript代码运行次数:0运行复制// 创建一个3通道(BGR)、8位无符号整数类型的300x400的图像

Mat image(300, 400, CV_8UC3); CV_8U : 8位无符号整数(通常用于像素值,范围0-255)

C3 : 3通道(例如,BGR颜色图像)

Python: 在Python中,图像数据存储为NumPy数组。你可以使用NumPy的函数来创建和操作图像数组。

Python

代码语言:javascript代码运行次数:0运行复制import numpy as np

# 创建一个3通道的300x400的图像,像素值初始化为0

image = np.zeros((300, 400, 3), dtype=np.uint8) (300, 400, 3): 表示图像的形状(高度、宽度、通道数)

dtype=np.uint8: 表示数据类型为8位无符号整数

5.3 读取与显示图像5.3.1 C++可以使用cv::imread()函数读取图像,使用cv::imshow()函数显示图像,使用cv::waitKey()函数等待按键,使用cv::destroyAllWindows()函数关闭所有窗口。

C++

代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

int main() {

// 读取图像

Mat image = imread("path/to/your/image.jpg");

// 检查图像是否成功加载

if (image.empty()) {

std::cout << "Could not open or find the image" << std::endl;

return -1;

}

// 显示图像

imshow("Display window", image);

// 等待按键 (0表示无限等待)

waitKey(0);

// 关闭所有窗口

destroyAllWindows();

return 0;

}5.3.2 Python可以使用cv2.imread()函数读取图像,使用cv2.imshow()函数显示图像,使用cv2.waitKey()函数等待按键,使用cv2.destroyAllWindows()函数关闭所有窗口。

Python

代码语言:javascript代码运行次数:0运行复制import cv2

# 读取图像

img = cv2.imread('path/to/your/image.jpg')

# 检查图像是否成功加载

if img is None:

print("Could not open or find the image")

else:

# 显示图像

cv2.imshow('image', img)

cv2.waitKey(0)

cv2.destroyAllWindows()注意: 请将 "path/to/your/image.jpg" 替换为实际的图像文件路径。

5.4 视频读写5.4.1 C++可以使用cv::VideoCapture类读取视频或摄像头数据,使用cv::VideoWriter类写入视频。

读取视频:

C++

代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

int main() {

// 打开视频文件

VideoCapture cap("path/to/your/video.mp4");

// 检查视频是否成功打开

if (!cap.isOpened()) {

std::cout << "Could not open the video file" << std::endl;

return -1;

}

while (true) {

Mat frame;

// 从视频中读取一帧

cap >> frame;

// 如果没有更多帧,则退出循环

if (frame.empty())

break;

// 显示帧

imshow("Video Frame", frame);

// 等待按键 (延迟25毫秒)

if (waitKey(25) >= 0)

break;

}

// 释放 VideoCapture 对象

cap.release();

destroyAllWindows();

return 0;

}写入视频:

C++

代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

int main() {

// 获取视频的属性 (例如,宽度、高度、帧率) - 这里假设你知道这些属性

int frame_width = 640;

int frame_height = 480;

double fps = 30.0;

// 创建 VideoWriter 对象

VideoWriter writer("output.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, Size(frame_width, frame_height));

// 检查 VideoWriter 对象是否成功创建

if (!writer.isOpened()) {

std::cout << "Could not open the output video file" << std::endl;

return -1;

}

// 创建一些帧并写入视频

for (int i = 0; i < 100; ++i) {

Mat frame(frame_height, frame_width, CV_8UC3, Scalar(i * 2, 255 - i * 2, 100));

writer.write(frame);

}

// 释放 VideoWriter 对象

writer.release();

return 0;

}5.4.2 Python可以使用cv2.VideoCapture()函数读取视频或摄像头数据,使用cv2.VideoWriter()函数写入视频。

读取视频:

Python

代码语言:javascript代码运行次数:0运行复制import cv2

# 打开视频文件

cap = cv2.VideoCapture('path/to/your/video.mp4')

# 检查视频是否成功打开

if not cap.isOpened():

print("Could not open the video file")

else:

while True:

ret, frame = cap.read()

# ret 是一个布尔值,表示是否成功读取到帧

# frame 是读取到的帧,如果成功读取则为图像数据,否则为 None

if not ret:

break

# 显示帧

cv2.imshow('Video Frame', frame)

# 等待按键 (延迟25毫秒)

if cv2.waitKey(25) & 0xFF == ord('q'):

break

# 释放 VideoCapture 对象

cap.release()

cv2.destroyAllWindows()写入视频:

Python

代码语言:javascript代码运行次数:0运行复制import cv2

# 获取视频的属性 (例如,宽度、高度、帧率) - 这里假设你知道这些属性

frame_width = 640

frame_height = 480

fps = 30.0

# 定义编码器和创建 VideoWriter 对象

fourcc = cv2.VideoWriter_fourcc(*'MJPG')

out = cv2.VideoWriter('output.avi', fourcc, fps, (frame_width, frame_height))

# 创建一些帧并写入视频

for i in range(100):

frame = np.zeros((frame_height, frame_width, 3), dtype=np.uint8)

frame[:] = [i * 2, 255 - i * 2, 100] # 设置颜色

out.write(frame)

# 释放 VideoWriter 对象

out.release()

cv2.destroyAllWindows()6. 常用方法详解接下来,我们将介绍一些OpenCV中常用的图像处理方法。

6.1 色彩空间转换OpenCV提供了多种色彩空间之间的转换功能,例如BGR(Blue, Green, Red)到灰度图、HSV(Hue, Saturation, Value)等。

6.1.1 C++使用cv::cvtColor()函数进行色彩空间转换。

C++

代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

int main() {

Mat image = imread("path/to/your/image.jpg");

if (image.empty()) return -1;

// 转换为灰度图

Mat gray_image;

cvtColor(image, gray_image, COLOR_BGR2GRAY);

imshow("Original Image", image);

imshow("Gray Image", gray_image);

waitKey(0);

destroyAllWindows();

// 转换为HSV色彩空间

Mat hsv_image;

cvtColor(image, hsv_image, COLOR_BGR2HSV);

imshow("HSV Image", hsv_image);

waitKey(0);

destroyAllWindows();

return 0;

}6.1.2 Python使用cv2.cvtColor()函数进行色彩空间转换。

代码语言:javascript代码运行次数:0运行复制import cv2

img = cv2.imread('path/to/your/image.jpg')

if img is None:

exit()

# 转换为灰度图

gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

cv2.imshow('Original Image', img)

cv2.imshow('Gray Image', gray_img)

cv2.waitKey(0)

cv2.destroyAllWindows()

# 转换为HSV色彩空间

hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

cv2.imshow('HSV Image', hsv_img)

cv2.waitKey(0)

cv2.destroyAllWindows()常用的色彩空间转换代码包括:

COLOR_BGR2GRAY: BGR到灰度

COLOR_BGR2HSV : BGR到HSV

COLOR_GRAY2BGR : 灰度到BGR

COLOR_HSV2BGR : HSV到BGR

6.2 图像阈值处理阈值处理用于将图像像素值二值化,即将大于或小于某个阈值的像素设置为一个特定的值。

6.2.1 C++使用cv::threshold()函数进行阈值处理。

代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

int main() {

Mat gray_image = imread("path/to/your/image.jpg", IMREAD_GRAYSCALE);

if (gray_image.empty()) return -1;

Mat thresh_binary;

threshold(gray_image, thresh_binary, 127, 255, THRESH_BINARY);

imshow("Binary Threshold", thresh_binary);

Mat thresh_binary_inv;

threshold(gray_image, thresh_binary_inv, 127, 255, THRESH_BINARY_INV);

imshow("Binary Inverse Threshold", thresh_binary_inv);

waitKey(0);

destroyAllWindows();

return 0;

}6.2.2 Python使用cv2.threshold()函数进行阈值处理。

代码语言:javascript代码运行次数:0运行复制import cv2

gray_img = cv2.imread('path/to/your/image.jpg', cv2.IMREAD_GRAYSCALE)

if gray_img is None:

exit()

ret, thresh_binary = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY)

cv2.imshow('Binary Threshold', thresh_binary)

ret, thresh_binary_inv = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY_INV)

cv2.imshow('Binary Inverse Threshold', thresh_binary_inv)

cv2.waitKey(0)

cv2.destroyAllWindows()常见的阈值类型包括:

THRESH_BINARY : 如果像素值大于阈值,则设置为最大值(通常为255),否则设置为0。

THRESH_BINARY_INV : 与 THRESH_BINARY相反。

THRESH_TRUNC : 如果像素值大于阈值,则设置为阈值,否则保持不变。

THRESH_TOZERO: 如果像素值大于阈值,则保持不变,否则设置为0。

THRESH_TOZERO_INV: 与 THRESH_TOZERO相反。

6.3 滤波与平滑滤波和平滑操作用于减少图像中的噪声。

6.3.1 C++常用的滤波方法包括均值滤波、高斯滤波、中值滤波等。

均值滤波:

代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

int main() {

Mat image = imread("path/to/your/image.jpg");

if (image.empty()) return -1;

Mat blur_image;

blur(image, blur_image, Size(5, 5));

imshow("Original Image", image);

imshow("Blurred Image", blur_image);

waitKey(0);

destroyAllWindows();

return 0;

}高斯滤波:

代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

int main() {

Mat image = imread("path/to/your/image.jpg");

if (image.empty()) return -1;

Mat gaussian_blur_image;

GaussianBlur(image, gaussian_blur_image, Size(5, 5), 0);

imshow("Original Image", image);

imshow("Gaussian Blurred Image", gaussian_blur_image);

waitKey(0);

destroyAllWindows();

return 0;

}中值滤波:

代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

int main() {

Mat image = imread("path/to/your/image.jpg");

if (image.empty()) return -1;

Mat median_blur_image;

medianBlur(image, median_blur_image, 5);

imshow("Original Image", image);

imshow("Median Blurred Image", median_blur_image);

waitKey(0);

destroyAllWindows();

return 0;

}6.3.2 Python均值滤波:

代码语言:javascript代码运行次数:0运行复制import cv2

img = cv2.imread('path/to/your/image.jpg')

if img is None:

exit()

blur_img = cv2.blur(img, (5, 5))

cv2.imshow('Original Image', img)

cv2.imshow('Blurred Image', blur_img)

cv2.waitKey(0)

cv2.destroyAllWindows()高斯滤波:

代码语言:javascript代码运行次数:0运行复制import cv2

img = cv2.imread('path/to/your/image.jpg')

if img is None:

exit()

gaussian_blur_img = cv2.GaussianBlur(img, (5, 5), 0)

cv2.imshow('Original Image', img)

cv2.imshow('Gaussian Blurred Image', gaussian_blur_img)

cv2.waitKey(0)

cv2.destroyAllWindows()中值滤波:

代码语言:javascript代码运行次数:0运行复制import cv2

img = cv2.imread('path/to/your/image.jpg')

if img is None:

exit()

median_blur_img = cv2.medianBlur(img, 5)

cv2.imshow('Original Image', img)

cv2.imshow('Median Blurred Image', median_blur_img)

cv2.waitKey(0)

cv2.destroyAllWindows()6.4 边缘检测边缘检测用于识别图像中亮度变化剧烈的区域。常用的边缘检测算法包括Canny、Sobel、Laplacian等。

6.4.1 C++Canny边缘检测:

代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

int main() {

Mat gray_image = imread("path/to/your/image.jpg", IMREAD_GRAYSCALE);

if (gray_image.empty()) return -1;

Mat canny_edges;

Canny(gray_image, canny_edges, 30, 100);

imshow("Original Image", gray_image);

imshow("Canny Edges", canny_edges);

waitKey(0);

destroyAllWindows();

return 0;

}6.4.2 PythonCanny边缘检测:

代码语言:javascript代码运行次数:0运行复制import cv2

gray_img = cv2.imread('path/to/your/image.jpg', cv2.IMREAD_GRAYSCALE)

if gray_img is None:

exit()

edges = cv2.Canny(gray_img, 30, 100)

cv2.imshow('Original Image', gray_img)

cv2.imshow('Canny Edges', edges)

cv2.waitKey(0)

cv2.destroyAllWindows()6.5 形态学操作形态学操作是基于图像形状的一些基本操作,如腐蚀、膨胀、开运算、闭运算等,常用于去除噪声、分离物体、连接断裂的区域等。

6.5.1 C++代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

int main() {

Mat binary_image = imread("path/to/your/binary_image.png", IMREAD_GRAYSCALE);

if (binary_image.empty()) return -1;

// 定义结构元素

Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));

// 膨胀

Mat dilated_image;

dilate(binary_image, dilated_image, kernel);

imshow("Dilated Image", dilated_image);

// 腐蚀

Mat eroded_image;

erode(binary_image, eroded_image, kernel);

imshow("Eroded Image", eroded_image);

waitKey(0);

destroyAllWindows();

return 0;

}6.5.2 Python代码语言:javascript代码运行次数:0运行复制import cv2

import numpy as np

binary_img = cv2.imread('path/to/your/binary_image.png', cv2.IMREAD_GRAYSCALE)

if binary_img is None:

exit()

# 定义结构元素

kernel = np.ones((5, 5), np.uint8)

# 膨胀

dilation = cv2.dilate(binary_img, kernel, iterations=1)

cv2.imshow('Dilated Image', dilation)

# 腐蚀

erosion = cv2.erode(binary_img, kernel, iterations=1)

cv2.imshow('Eroded Image', erosion)

cv2.waitKey(0)

cv2.destroyAllWindows()常用的形态学操作包括:

MORPH_ERODE: 腐蚀MORPH_DILATE : 膨胀MORPH_OPEN : 开运算(先腐蚀后膨胀)MORPH_CLOSE : 闭运算(先膨胀后腐蚀)6.6 轮廓检测轮廓检测用于找到图像中物体的边界。

6.6.1 C++代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

#include

int main() {

Mat binary_image = imread("path/to/your/binary_image.png", IMREAD_GRAYSCALE);

if (binary_image.empty()) return -1;

std::vector> contours;

std::vector hierarchy;

findContours(binary_image, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);

Mat image_with_contours = Mat::zeros(binary_image.size(), CV_8UC3);

for (size_t i = 0; i < contours.size(); i++) {

drawContours(image_with_contours, contours, (int)i, Scalar(0, 0, 255), 2, LINE_8, hierarchy, 0);

}

imshow("Original Binary Image", binary_image);

imshow("Image with Contours", image_with_contours);

waitKey(0);

destroyAllWindows();

return 0;

}6.6.2 Python代码语言:javascript代码运行次数:0运行复制import cv2

binary_img = cv2.imread('path/to/your/binary_image.png', cv2.IMREAD_GRAYSCALE)

if binary_img is None:

exit()

contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

image_with_contours = cv2.cvtColor(binary_img, cv2.COLOR_GRAY2BGR)

cv2.drawContours(image_with_contours, contours, -1, (0, 0, 255), 2)

cv2.imshow('Original Binary Image', binary_img)

cv2.imshow('Image with Contours', image_with_contours)

cv2.waitKey(0)

cv2.destroyAllWindows()6.7 几何变换几何变换包括图像的缩放、平移、旋转、仿射变换和透视变换等。

6.7.1 C++缩放:

代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

int main() {

Mat image = imread("path/to/your/image.jpg");

if (image.empty()) return -1;

Mat resized_image;

resize(image, resized_image, Size(), 2.0, 2.0, INTER_LINEAR); // 放大两倍

imshow("Original Image", image);

imshow("Resized Image", resized_image);

waitKey(0);

destroyAllWindows();

return 0;

}6.7.2 Python缩放:

代码语言:javascript代码运行次数:0运行复制import cv2

img = cv2.imread('path/to/your/image.jpg')

if img is None:

exit()

resized_img = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_LINEAR) # 放大两倍

cv2.imshow('Original Image', img)

cv2.imshow('Resized Image', resized_img)

cv2.waitKey(0)

cv2.destroyAllWindows()6.8 绘制函数OpenCV提供了一些用于在图像上绘制基本形状的函数,如直线、矩形、圆、文本等。

6.8.1 C++代码语言:javascript代码运行次数:0运行复制#include

using namespace cv;

int main() {

Mat image(300, 400, CV_8UC3, Scalar(255, 255, 255)); // 创建白色图像

// 绘制直线

line(image, Point(50, 50), Point(350, 250), Scalar(255, 0, 0), 3);

// 绘制矩形

rectangle(image, Point(100, 100), Point(300, 200), Scalar(0, 255, 0), 2);

// 绘制圆形

circle(image, Point(200, 150), 40, Scalar(0, 0, 255), -1); // -1 表示填充

// 绘制文本

putText(image, "Hello OpenCV", Point(50, 280), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 0), 2);

imshow("Drawing", image);

waitKey(0);

destroyAllWindows();

return 0;

}6.8.2 Python代码语言:javascript代码运行次数:0运行复制import cv2

import numpy as np

img = np.zeros((300, 400, 3), dtype=np.uint8) + 255 # 创建白色图像

# 绘制直线

cv2.line(img, (50, 50), (350, 250), (255, 0, 0), 3)

# 绘制矩形

cv2.rectangle(img, (100, 100), (300, 200), (0, 255, 0), 2)

# 绘制圆形

cv2.circle(img, (200, 150), 40, (0, 0, 255), -1) # -1 表示填充

# 绘制文本

cv2.putText(img, "Hello OpenCV", (50, 280), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)

cv2.imshow('Drawing', img)

cv2.waitKey(0)

cv2.destroyAllWindows()7. 进阶技巧在掌握了基本语法和常用方法后,你可以尝试一些更高级的技巧。

7.1 ROI 与模板匹配ROI (Region of Interest) 是图像中你感兴趣的区域,可以单独对这部分区域进行处理。模板匹配是在一个大图中搜索与给定模板图像最相似的区域。

7.2 特征检测(ORB/SIFT/SURF)特征检测算法用于提取图像中具有代表性的点(特征点),这些特征点在图像匹配、物体识别等任务中非常有用。常见的算法有ORB、SIFT、SURF等。

7.3 摄像头标定与透视变换摄像头标定是获取摄像头内外参数的过程,可以用于校正图像畸变。透视变换可以将图像从一个视角变换到另一个视角,常用于图像矫正和拼接。

由于篇幅有限,这些进阶技巧将在后续的文章中详细介绍。

8. 常见问题与解决方案导入cv2模块失败: 确保OpenCV已经成功安装,并且Python环境配置正确。尝试重新安装或检查Python路径。无法打开图像或视频: 检查文件路径是否正确,文件是否存在,以及文件格式是否受OpenCV支持。编译错误: 检查CMake配置是否正确,依赖库是否安装完整,以及编译命令是否正确。运行缓慢: 尝试优化代码,例如减小图像尺寸,使用更高效的算法等。对于C++,可以尝试Release模式编译。如果在学习过程中遇到其他问题,欢迎在评论区提问,或者加我的微信与我交流。

9. 总结与建议恭喜你!通过本文的学习,你已经对OpenCV的安装、配置、基本语法和常用方法有了初步的了解。计算机视觉是一个充满挑战和乐趣的领域,OpenCV作为强大的工具,将帮助你实现各种有趣的想法。

我的建议是:

多动手实践: 学习编程最好的方式就是不断练习,尝试用OpenCV处理不同的图像和视频。查阅官方文档: OpenCV的官方文档非常详细,遇到问题时可以查阅官方文档获取更深入的理解。参与社区交流: 积极参与OpenCV相关的论坛、社区,与其他开发者交流学习经验。持续学习: 计算机视觉技术发展迅速,保持学习的热情,不断探索新的知识和技术。10. 参考资料OpenCV官方网站OpenCV官方GitHub仓库OpenCV Contrib GitHub仓库NumPy官方网站Matplotlib官方网站其他相关的技术博客和教程

相关推荐

世界杯新闻媒体如何重塑赛事报道格局与观众互动体验
体育投注365下载

世界杯新闻媒体如何重塑赛事报道格局与观众互动体验

📅 08-30 👁️ 6947
3WPS如何启用宏
体育投注365下载

3WPS如何启用宏

📅 07-14 👁️ 6905
分享一些关于小雅Alist的使用心得
365bet体育投注官网

分享一些关于小雅Alist的使用心得

📅 09-19 👁️ 9988