opencv|opencv入门

【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);

显示效果:
opencv|opencv入门
文章图片

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
  • 第一个参数是图像保存路径
  • 第二个参数是图像内存对象
hsv和GRAY
  • 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|opencv入门
文章图片

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;

opencv|opencv入门
文章图片

使用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;

opencv|opencv入门
文章图片

而如果是使用Mat::zeros方法时,并不会发送该情况,而是全部会初始化为0。
Mat m3 = Mat::zeros(Size(8, 8), CV_8UC3);

opencv|opencv入门
文章图片

改变空白对象的色彩
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也会收到影响。
opencv|opencv入门
文章图片

解决的方案就是让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|opencv入门
文章图片

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入门
文章图片

    推荐阅读