一、前言
本系列博文目的在于带领新人快速入门,因此对于图像处理的基本理论不做详细讲解,直接上手干活,在代码中学习。个人认为这是学习技术最快的方式。
二、代码片段
2.1、读取图像
cv::Mat src = cv::imread("../data/image/beautiful_girl.jpg", cv::IMREAD_UNCHANGED);
// 注释:
// imread函数的第一个参数是路径,第二个参数是读取方式,有以下读取方式:
/*
enum ImreadModes {
IMREAD_UNCHANGED = -1, 不改变原图 --常用
IMREAD_GRAYSCALE = 0, 单通道灰度图 -- 常用
IMREAD_COLOR = 1, BGR彩色图 --- 常用
IMREAD_ANYDEPTH = 2, 32bit/64bit等 --- 常用于读取深度图
IMREAD_ANYCOLOR = 4, 任意可能的彩色格式 -- 不常用
IMREAD_LOAD_GDAL = 8, 以下方式均不常用,使用时现查即可
IMREAD_REDUCED_GRAYSCALE_2 = 16,
IMREAD_REDUCED_COLOR_2 = 17,
IMREAD_REDUCED_GRAYSCALE_4 = 32,
IMREAD_REDUCED_COLOR_4 = 33,
IMREAD_REDUCED_GRAYSCALE_8 = 64,
IMREAD_REDUCED_COLOR_8 = 65,
IMREAD_IGNORE_ORIENTATION = 128
};
*/
2.2、修改图像尺寸
cv::Mat src_resize;
cv::resize(src, src_resize, cv::Size(src.cols / 1.3, src.rows / 2));
// 注释:
/*
resize函数用于修改图像尺寸
cv::Size(col,row), ----- Size中,先列后行
*/
2.3、色彩空间变换
cv::Mat gray;
cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
// 注释
/* cvtColor函数用于图像色彩空间转换,以下列出部分常用转换方式:
(均可见名知义)
COLOR_BGR2GRAY 彩色图转换为灰度图
COLOR_BGR2RGB 彩色图通道调换顺序
COLOR_BGR2HSV BGR转换到HSV
COLOR_HSV2BGR HSV转换到BGR
COLOR_GRAY2BGR 灰度图转换为三通道彩色图(转换后人眼无法分辨)
...
*/
2.4、阈值分割
cv::Mat thre;
cv::threshold(src, thre, 128, 255, cv::THRESH_BINARY);
//注释
/* 阈值分割方式:
enum ThresholdTypes {
THRESH_BINARY = 0, 固定阈值分割,初学者最喜欢使用,但实际上很对场景并不适用
THRESH_BINARY_INV = 1, 固定阈值反分割
THRESH_TRUNC = 2,
THRESH_TOZERO = 3,
THRESH_TOZERO_INV = 4,
THRESH_MASK = 7,
THRESH_OTSU = 8, 大津阈值分割
THRESH_TRIANGLE = 16
};
2.5、显示图像
cv::namedWindow("image_show"); // 创建窗口,可缺省
cv::imshow("image_show", src_resize); // 显示图像
cv::waitKey(0); // 避免窗口一闪而过
2.6、获取某点像素值
注意:访问时先行后列
int gray_value = gray.at<uchar>(50, 100); // row 50,col 100
std::cout << "gray_value:" << gray_value << std::endl;
cv::Vec3b bgr = src.at<cv::Vec3b>(50, 100);
std::cout << "bgr" << bgr << std::endl;
std::cout << "bgr[0]:" << int(bgr[0]) << std::endl;
std::cout << "bgr[1]:" << int(bgr[1]) << std::endl;
std::cout << "bgr[2]:" << int(bgr[2]) << std::endl;
2.7、修改像素值
gray.at<uchar>(50, 100) = 0;
src.at<cv::Vec3b>(50, 100) = cv::Vec3b(100, 100, 100);
2.8、图像上添加文字
cv::putText(src, "beautiful girl", cv::Point(100, 100), 3, 1, cv::Scalar(0, 255, 0), 5);
2.9、绘制图案
cv::line(src, cv::Point(50, 100), cv::Point(100, 100), cv::Scalar(255, 0, 0), 1);
cv::rectangle(src, cv::Rect(200, 200, 200, 400), cv::Scalar(0, 255, 0), 1);
cv::circle(src, cv::Point(50, 100), 50, cv::Scalar(0, 0, 255), 1);
2.10、矩形区域截取图像
cv::Rect rect(200, 200, 200, 400);
cv::Mat roi = src(rect);
三、完整代码
#include <opencv2/opencv.hpp>
#include <opencv2/core/utils/logger.hpp>
int main()
{
// 设置只输出错误日志
cv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_ERROR);
// 读取图像通道不变+
cv::Mat src = cv::imread("../data/image/beautiful_girl.jpg", cv::IMREAD_UNCHANGED);
// 修改图像尺寸,cv::Size(col,row),列在前行在后
cv::Mat src_resize;
cv::resize(src, src_resize, cv::Size(src.cols / 1.3, src.rows / 2));
// 打开窗口
cv::namedWindow("image_show");
// 显示图像
cv::imshow("image_show", src_resize);
// 避免窗口一闪而过
cv::waitKey(0);
// BGR转GRAY
cv::Mat gray;
cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
cv::imshow("image_show", gray);
cv::waitKey(0);
// 固定阈值分割
cv::Mat thre;
cv::threshold(src, thre, 128, 255, cv::THRESH_BINARY);
cv::imshow("image_show", thre);
cv::waitKey(0);
// 获取某点像素值
int gray_value = gray.at<uchar>(50, 100);
std::cout << "gray_value:" << gray_value << std::endl;
cv::Vec3b bgr = src.at<cv::Vec3b>(50, 100);
std::cout << "bgr" << bgr << std::endl;
std::cout << "bgr[0]:" << int(bgr[0]) << std::endl;
std::cout << "bgr[1]:" << int(bgr[1]) << std::endl;
std::cout << "bgr[2]:" << int(bgr[2]) << std::endl;
// 修改某点像素值
gray.at<uchar>(50, 100) = 0;
src.at<cv::Vec3b>(50, 100) = cv::Vec3b(100, 100, 100);
cv::imshow("image_show", gray);
cv::imshow("image_show", src);
cv::waitKey(0);
// 图片上添加文字
cv::putText(src, "beautiful girl", cv::Point(100, 100), 3, 1, cv::Scalar(0, 255, 0), 5);
cv::imshow("image_show", src);
cv::waitKey(0);
// 绘制图案
cv::line(src, cv::Point(50, 100), cv::Point(100, 100), cv::Scalar(255, 0, 0), 1);
cv::rectangle(src, cv::Rect(200, 200, 200, 400), cv::Scalar(0, 255, 0), 1);
cv::circle(src, cv::Point(50, 100), 50, cv::Scalar(0, 0, 255), 1);
cv::imshow("image_show", src);
cv::waitKey(0);
// 矩形截取图像ROI
cv::Rect rect(200, 200, 200, 400);
cv::Mat roi = src(rect);
cv::imshow("roi", roi);
cv::waitKey(0);
return 0;
}
四、运行程序
前提:按上一篇文章所属配置好VS2022与OpenCV4.9.0开发环境,将代码输入编辑界面,运行程序:可得类似如下图像: