【opencv|opencv入门】
目录
- 窗口显示
- 图片色彩的转换
-
- 1.色彩空间转换函数- cvtColor
- 2.图像保存- imwrite
- openCV图像对象创建与赋值
- opencv图像像素点读写操作
- 图像像素的算术操作
窗口显示 图片的显示
#include
#include
using namespace cv;
using namespace std;
int main()
{
cv::Mat src = https://www.it610.com/article/imread("C:/Users/26961/Desktop/dog.jpg");
if (src.empty()) {
cout << "图图片未加载" << endl;
return -1;
}
imshow("输入窗口", src);
waitKey(0);
//阻塞式等待
destroyAllWindows();
//销毁所有的窗口对象
return 0;
}
并不能进行窗口的缩放,只是图片固定在创建的窗口上会固定尺寸注意:
- imread可以加载灰度图像
cv::Mat src = https://www.it610.com/article/imread("C:/Users/26961/Desktop/dog.jpg",
IMREAD_GRAYSCALE);
显示效果:
文章图片
namedWindow 可以进行窗口的缩放
#include
#include
using namespace cv;
using namespace std;
int main()
{
cv::Mat src = https://www.it610.com/article/imread("C:/Users/26961/Desktop/dog.jpg");
if (src.empty()) {
cout << "图片未加载" << endl;
return -1;
}
//可以进行窗口的缩放
namedWindow("输入窗口", WINDOW_FREERATIO);
//WINDOW_FREERATIO -可以调整图片的自由比率
imshow("输入窗口", src);
waitKey(0);
//阻塞式等待
destroyAllWindows();
return 0;
}
图片色彩的转换 1.色彩空间转换函数- cvtColor
COLOR_ BGR2GRAY = 6彩色到灰度
COLOR_ _GRAY2BGR= 8灰度到彩色
COLOR_ BGR2HSV = 40 BGR到HSV
COLOR_ HSV2BGR = 54 HSV到BGR
2.图像保存- imwrite
- 第一个参数是图像保存路径
- 第二个参数是图像内存对象
- H 、S 、V三个通道的取值范围在0~180之间, H、S可以改变图片的色彩,V可以改变图片的亮度。
void QuickDemo::quick_space_demo(Mat& src)
{
Mat gray, hsv;
//用于存储灰色和彩色的Mat对象
cvtColor(src, hsv, COLOR_BGR2HSV);
//设置灰色
cvtColor(src, gray, COLOR_BGR2GRAY);
//设置彩色
//调整图片的自由比率
namedWindow("灰色", WINDOW_FREERATIO);
namedWindow("hsv", WINDOW_FREERATIO);
imshow("hsv", hsv);
//显示转换后的图片
imshow("灰色", gray);
//显示转换后的图片 //保存转换颜色后的图片
imwrite("C:/Users/26961/Desktop/images/hsv.jpg", hsv);
imwrite("C:/Users/26961/Desktop/images/gray.jpg", gray);
}
main.cpp
#include
#include
#include "quick_demo.h"using namespace cv;
using namespace std;
int main()
{
cv::Mat src = https://www.it610.com/article/imread("C:\\Users\\26961\\Desktop\\images\\dog.jpg");
if (src.empty()) {
cout << "图片未打开" << endl;
return -1;
} //可以进行窗口的缩放,图片与窗口大小匹配
namedWindow("输入窗口", WINDOW_FREERATIO);
imshow("输入窗口", src);
//彩色转换
QuickDemo obj;
obj.quick_space_demo(src);
//将Mat 对象传递给quick_space_demo函数,将转换的图片保存到
// C:/Users/26961/Desktop/images/路径中 //阻塞等待
waitKey(0);
//销毁窗口对象
destroyAllWindows();
return 0;
}
文章图片
openCV图像对象创建与赋值 图像对象的创建和赋值
void QuickDemo::mat_creater_demo(Mat& src)
{
Mat m1, m2;
m1 = src.clone();
//赋值方式一
src.copyTo(m2);
//赋值方式二
cvtColor(src, m1, COLOR_BGR2HSV);
//为了区别,将m1对象色彩设置为彩色 imshow("m1对象", m1);
imshow("m2对象", m2);
}
创建 8 * 8 的空白对象
//设置8 * 8的空白图像,指定一个通道。
Mat m3 = Mat::zeros(Size(8, 8), CV_8UC1);
/*
显示宽度、高度、通道。
*/
std::cout << "width: " << m3.cols << " height: " << m3.rows
<< " channels: " << m3.channels() << std::endl;
//打印空白图像
std::cout << m3 << std::endl;
文章图片
使用ones和zeros的区别
如果在创建空白Mat对象时,如果指定要创建3个通道的时候,但是此时是使用Mat::ones该方法进行创建的话都出现1和0交替的现象,并且1总是出现在1通道
Mat m3 = Mat::ones(Size(8, 8), CV_8UC3);
std::cout << "width: " << m3.cols << " height: " << m3.rows
<< " channels: " << m3.channels() << std::endl;
文章图片
而如果是使用Mat::zeros方法时,并不会发送该情况,而是全部会初始化为0。
Mat m3 = Mat::zeros(Size(8, 8), CV_8UC3);
文章图片
改变空白对象的色彩
Mat m3 = Mat::zeros(Size(500, 500), CV_8UC3);
m3 = Scalar(255,0,0);
//设置m3对象的色彩,这里会被设置为纯蓝色
imshow("图像", m3);
//显示m3对象
Mat对象之间的深浅拷贝问题
void QuickDemo::mat_creater_demo(Mat& src)
{
Mat m1, m2;
m1 = src.clone();
//赋值方式一
src.copyTo(m2);
//赋值方式二
cvtColor(src, m1, COLOR_BGR2HSV);
//为了区别,将m1对象色彩设置为彩色 /*imshow("m1对象", m1);
imshow("m2对象", m2);
*/ Mat m3 = Mat::zeros(Size(500, 500), CV_8UC3);
m3 = Scalar(255,0,0);
//设置m3对象的色彩
imshow("图像3", m3);
std::cout << "width: " << m3.cols << " height: " << m3.rows
<< " channels: " << m3.channels() << std::endl;
//浅拷贝
Mat m4 = m3;
m4 = Scalar(0, 0 ,0);
//修改了m3
imshow("图像4", m4);
//深拷贝
Mat m5 = m3.clone();
//深拷贝已经修改了的m3
imshow("图像5", m5);
}
如果只是单纯的进行浅拷贝的话,那么m4对象的改变会影响到m3对象, 直到m4被修改了后m3也会收到影响。
文章图片
解决的方案就是让m4深拷贝m3,那么就不会导致m3发生改变
void QuickDemo::mat_creater_demo(Mat& src)
{
Mat m3 = Mat::zeros(Size(500, 500), CV_8UC3);
m3 = Scalar(255,0,0);
//设置m3对象的色彩
imshow("图像3", m3);
std::cout << "width: " << m3.cols << " height: " << m3.rows
<< " channels: " << m3.channels() << std::endl;
//浅拷贝
Mat m4 = m3.clone();
m4 = Scalar(0, 0 ,0);
imshow("图像4", m4);
//深拷贝
Mat m5 = m3.clone();
m5 = Scalar(160,20,20);
imshow("图像5", m5);
}
效果:
文章图片
opencv图像像素点读写操作
- 数组遍历
void changeimg(Mat &src) { int w = src.cols;
//列
int h = src.rows;
//行
int dims = src.channels();
//通道 for (int i = 0;
i < h;
i++) {
for (int j = 0;
j < w;
j++) {
if (dims == 1) { //单通道的灰度图像//获取[i, j]位置的像素值
int pv = src.at(i, j);
//修改[i, j]位置的像素值
src.at(i, j) = 255 - pv;
}//三个通道的像素点需要修改三次,因为三个通道的彩色图像每一个像素点可以存储3个值
if (dims == 3) { //3通道的彩色图像//Vec3b 是一个三通道的像素点,所以Vec3b对象包含三个值
Vec3b bgr = src.at(i, j);
src.at(i, j)[0] = 255 - bgr[0];
src.at(i, j)[1] = 255 - bgr[1];
src.at(i, j)[2] = 255 - bgr[2];
}
}
}
}void QuickDemo::pixel_vlist_demo(Mat& src) {
Mat m1 = src.clone();
changeimg(m1);
imshow("src图像", src);
Mat m2 = src.clone();
changeimg(m2);
imshow("m2图像", m2);
}
修改前 vs 修改后
- 指针方式遍历
void changeimg2(Mat& src) { int w = src.cols;
//列
int h = src.rows;
//行
int dims = src.channels();
//通道 for (int i = 0;
i < h;
i++) {
// 获取行指针
uchar* curr_row = src.ptr(i);
for (int j = 0;
j < w;
j++) {//获取列指针
if (dims == 1) {
int pv = *curr_row;
*curr_row++ = 255 - pv;
}
if (dims == 3) {
//遍历一个像素点拥有三个值的图像
*curr_row++ = 255 - *curr_row;
*curr_row++ = 255 - *curr_row;
*curr_row++ = 255 - *curr_row;
}
}
}}void QuickDemo::pixel_vlist_demo(Mat& src) {
Mat m1 = src.clone();
changeimg1(m1);
imshow("src图像", m1);
Mat m2 = src.clone();
changeimg2(m2);
imshow("m2图像", m2);
}
图像像素的算术操作 除法操作两种方式
void QuickDemo::operator_demo(Mat& src)
{
Mat dst;
dst = src / Scalar(2, 2, 2);
imshow("算术操作", dst);
}void QuickDemo::operator_demo(Mat& src)
{
Mat dst;
Mat m = Mat::zeros(src.size(), src.type());
m = Scalar(2, 2, 2);
divide(src, m, dst);
imshow("除法操作", dst);
}
乘法操作
void QuickDemo::operator_demo(Mat& src)
{
Mat dst;
Mat m = Mat::zeros(src.size(), src.type());
m = Scalar(2, 2, 2);
multiply(src, m, dst);
//src 与 m相乘的结果放入dst中
imshow("算术操作", dst);
}
像素点相加
void QuickDemo::operator_demo(Mat& src)
{
//初始化dst, 用于存储m和src 运算后的结果值
Mat dst = Mat::zeros(src.size(), src.type());
//初始化m对象
Mat m = Mat::zeros(src.size(), src.type());
m = Scalar(2, 2, 2);
int h = src.rows;
//获取行
int w = src.cols;
//获取列
//计算 m对象和src的和值
for (int i = 0;
i < h;
i++) {
for (int j = 0;
j < w;
j++) {
Vec3b p1 = src.at(i, j);
Vec3b p2 = m.at(i, j);
dst.at(i, j)[0] = saturate_cast(p1[0] + p2[0]);
dst.at(i, j)[1] = saturate_cast(p1[1] + p2[1]);
dst.at(i, j)[2] = saturate_cast(p1[2] + p2[2]);
}
} imshow("算术操作", dst);
}
算术运算常用的四个接口
//加法
void add(src, m, dst);
//减法
void subtract(src, m, dst);
//乘法
void multiply(src, m, dst);
//除法
void divide(src, m, dst);
文章图片
推荐阅读
- opencv|小白写程序之利用OpenCV Dlib Face_Recognition进行人脸识别操作
- 树莓派+python|树莓派+python+Opencv+face_confignition实现实时人脸识别(人脸识别门禁系统)
- 计算机视觉|【人脸检测】基于OpenCV和Face_Recognition实现人脸检测
- SfM|猿创征文|SfM(Structure from Motion)学习之路
- YOLOv5|基于改进YOLOv5轻量化的烟火检测
- 缺陷检测|汇总 | 深度学习实现缺陷检测方法
- YOLOv7|YOLOv7 训练报错 IndexError: list index out of range
- #|AI-无损检测方向速读(基于深度学习的表面缺陷检测方法综述)
- 算法|总结|深度学习实现缺陷检测