当前位置:   article > 正文

opencv c++编程基础_opencv c++入门

opencv c++入门

1、图片的本质

图像在 OpenCV 中的本质

OpenCV 中,图像被表示为一个多维数组,其中每个元素对应于图像中的单个像素。图像的维度取决于其通道数和像素数。

  • **通道数:**图像可以有多个通道,每个通道存储图像的不同信息。例如,彩色图像通常有 3 个通道(红色、绿色和蓝色),而灰度图像只有一个通道。
  • **像素数:**图像的像素数决定了其宽度和高度。

图像存储方式

OpenCV 中的图像通常以以下格式存储:

  • **Mat:**这是 OpenCV 中最常用的图像表示形式。Mat 是一个多维数组,可以存储不同类型的图像数据(例如,uint8、float32 等)。
  • **IplImage:**这是一个旧的图像表示形式,在 OpenCV 2.0 之前使用。它与 Mat 类似,但有一些限制。

Mat 中图像的存储

Mat 中的图像数据以行优先顺序存储。这意味着图像的第一个维度对应于行,而第二个维度对应于列。对于一个 3 通道的彩色图像,Mat 中的元素顺序如下:

[B00, G00, R00, B01, G01, R01, ..., Bmn, Gmn, Rmn]

其中:

  • BGR 表示蓝色、绿色和红色通道
  • mn 是图像的高度和宽度

通道的顺序

OpenCV 中图像的通道顺序通常为 BGR(蓝色、绿色、红色)。这与其他一些图像处理库(如 PIL)中使用的 RGB 顺序不同。

其他图像存储格式

除了 Mat 和 IplImage 之外,OpenCV 还支持其他图像存储格式,包括:

  • **UMat:**一种优化的 Mat,可利用 GPU 加速。
  • **cuda::GpuMat:**一种专用于 GPU 处理的 Mat。
  • **std::vector<uchar>:**一种使用标准 C++ 向量存储图像数据的格式。

2、Mat

从文件读取图片并显示

  1. #include <iostream>
  2. #include "opencv2/core.hpp"
  3. #include <opencv2/imgcodecs.hpp>
  4. #include <opencv2/highgui.hpp>
  5. using namespace std;
  6. using namespace cv;
  7. int main(){
  8. Mat image;
  9. image = imread("firefox.png"); //imread()读取图片
  10. if(!image.empty()){
  11. imshow("1",image); //imshow展示图片,前面为展示名,后面为图片。
  12. waitKey(0);
  13. }
  14. destroyAllWindows();
  15. return 0;
  16. }

从文件读取图片并显示

waitKey(0) 是 OpenCV 中的一个函数,用于等待用户按下一个键。它有以下作用:

  • 暂停程序执行:waitKey(0) 会暂停程序执行,直到用户按下一个键。这通常用于在显示图像或视频时让用户有机会查看内容。
  • **获取按键:**当用户按下一个键时,waitKey(0) 会返回该键的 ASCII 码。这可用于检测用户输入并做出相应操作。
  • 无限等待:waitKey(0) 的参数为 0 表示无限等待。这意味着程序将一直暂停,直到用户按下一个键。

使用示例:

  1. cv::Mat image = cv::imread("image.png");
  2. cv::imshow("Image", image);
  3. cv::waitKey(0);

在上面的示例中,程序将暂停执行,直到用户按下一个键。然后,程序将继续执行,关闭图像窗口并释放资源。

注意:

  • waitKey(0) 是一个阻塞函数,这意味着它会阻止程序执行,直到用户按下一个键。
  • 如果您不希望程序暂停执行,可以使用 waitKey(1),它将等待 1 毫秒的按键输入。如果在此期间没有按键输入,程序将继续执行。
  • waitKey(0) 通常用于交互式应用程序,例如图像查看器或视频播放器。

展示结果:

图片大小resize函数

resize后保存为新图片

  1. #include <iostream>
  2. #include "opencv2/core.hpp"
  3. #include <opencv2/imgcodecs.hpp>
  4. #include <opencv2/highgui.hpp>
  5. #include <opencv2/core/mat.hpp>
  6. #include <opencv2/imgproc.hpp>
  7. using namespace std;
  8. using namespace cv;
  9. int main(){
  10. Mat image;
  11. image = imread("firefox.png"); //imread()读取图片
  12. if(!image.empty()){
  13. imshow("image",image); //imshow展示图片,前面为展示名,后面为图片。
  14. waitKey(0);
  15. }
  16. // destroyAllWindows();
  17. Mat resize_image;
  18. resize(image, resize_image, Size(), 1, 0.5); //resize()改变大小 前为高度 后为宽度
  19. if(!image.empty()){
  20. imshow("resize",resize_image);
  21. waitKey(0);
  22. }
  23. imwrite("resize.png",resize_image); //imwrite(文件名,图片)写入文件 需要指定扩展名,否则exception
  24. destroyAllWindows();
  25. return 0;
  26. }

图片旋转

getRotationMatrix2D()和warpAffine()函数

  1. Mat rotated_image;
  2. double angle = 90; //旋转角度
  3. Point2f center(image.cols / 2.0, image.rows / 2.0); //获取旋转中心
  4. Mat rotation_matix = getRotationMatrix2D(center, angle, 0.5); //getRotationMatrix2D()计算旋转矩阵 参数:旋转中心、旋转角度、放大倍数
  5. warpAffine(image, rotated_image, rotation_matix, image.size()); //warpAffine旋转图片 参数:原图、目标图片、旋转矩阵、生成图片的大小
  6. if(!rotated_image.empty()){
  7. imshow("rotate",rotated_image);
  8. waitKey(0);
  9. }
  10. imwrite("rotate.png",rotated_image);
  11. destroyAllWindows();

Point2f 是 OpenCV 中的一个结构,用于表示二维点。它包含两个浮点成员:xy,分别表示点的横坐标和纵坐标。

声明:

  1. struct Point2f {
  2. float x;
  3. float y;
  4. };

构造函数:

  • **Point2f():**创建一个默认构造的 Point2f,其中 xy 都为 0。
  • **Point2f(float x, float y):**创建一个 Point2f,其中 xy 设置为指定的值。

图片平移

warpAffine()函数和平移矩阵

平移矩阵:

平移矩阵是一个 2x3 的仿射变换矩阵,

  1. [ 1 0 tx ]
  2. [ 0 1 ty ]

其中:

  • tx 是水平平移量。
  • ty 是垂直平移量。

为tx提供正值将使图像向右移动,而负值将使图像向左移动。

同样,ty值为正值时,图像会向下平移,而ty值为负值时,图像会向上平移。

warpAffine()本质是仿射变换。

3、这里可以看到调整了大小或者平移过后窗口大小存在一些问题,:

可以使用 OpenCV 的 namedWindow() 函数来设置 imshow() 窗口的大小。

示例:

  1. cv::namedWindow("Image", cv::WINDOW_NORMAL); // 创建一个可调整大小的窗口
  2. cv::imshow("Image", image);
  3. // 设置窗口大小
  4. cv::resizeWindow("Image", 640, 480);

参数:

  • **window_name:**窗口的名称。
  • **flag:**一个标志,指定窗口的类型。WINDOW_NORMAL 创建一个可调整大小的窗口。

其他标志:

  • **WINDOW_AUTOSIZE:**窗口大小自动调整为图像大小。
  • **WINDOW_FREERATIO:**窗口可以自由调整大小,而无需保持图像的宽高比。
  • **WINDOW_FULLSCREEN:**窗口以全屏模式显示。

注意:

  • namedWindow() 函数必须在 imshow() 函数之前调用。
  • 窗口大小只能在创建窗口后设置。
  • 窗口大小设置仅适用于可调整大小的窗口(即使用 WINDOW_NORMAL 标志创建的窗口)。

图片拼接

在 OpenCV 中,可以使用 hconcat()vconcat() 函数水平和垂直拼接图像。

水平拼接(并排):

  1. cv::Mat image1 = cv::imread("image1.png");
  2. cv::Mat image2 = cv::imread("image2.png");
  3. cv::Mat拼接图像;
  4. cv::hconcat(std::vector[cv::Mat](cv::Mat){image1, image2},拼接图像);

垂直拼接(上下):

  1. cv::Mat image1 = cv::imread("image1.png");
  2. cv::Mat image2 = cv::imread("image2.png");
  3. cv::Mat拼接图像;
  4. cv::vconcat(std::vector[cv::Mat](cv::Mat){image1, image2},拼接图像);

参数:

  • **images:**要拼接的图像的向量。
  • **拼接图像:**用于存储拼接图像的 Mat 对象。

注意:

  • 要拼接的图像必须具有相同的通道数和深度。
  • hconcat()vconcat() 函数将自动调整图像大小以匹配。
  • 拼接图像的尺寸取决于要拼接的图像的尺寸和拼接的方向。

图片翻转

在 OpenCV 中,可以使用 flip() 函数水平或垂直翻转图像。

水平翻转:

  1. cv::Mat image = cv::imread("image.png");
  2. cv::Mat flipped_image;
  3. // 水平翻转
  4. cv::flip(image, flipped_image, 1);

垂直翻转:

  1. cv::Mat image = cv::imread("image.png");
  2. cv::Mat flipped_image;
  3. // 垂直翻转
  4. cv::flip(image, flipped_image, 0);

参数:

  • **image:**要翻转的图像。
  • **flipped_image:**用于存储翻转后图像的 Mat 对象。
  • **flipCode:**指定翻转方向的标志。

flipCode 标志:

  • **0:**垂直翻转
  • **1:**水平翻转
  • **-1:**水平和垂直翻转

注意:

  • 翻转图像不会修改原始图像。
  • 翻转图像可能会导致图像质量下降,尤其是在翻转包含文本或其他非对称特征的图像时。

高斯模糊

在 OpenCV 中,可以使用 GaussianBlur() 函数对图像应用高斯模糊。

示例

  1. cv::Mat image = cv::imread("image.png");
  2. cv::Mat blurred_image;
  3. // 高斯模糊
  4. cv::GaussianBlur(image, blurred_image, cv::Size(5, 5), 0);

参数

**image:**要模糊的图像。

**blurred_image:**用于存储模糊后图像的 Mat 对象。

**kernel_size:**模糊核的大小。它必须是一个奇数。

**sigmaX:**高斯核在 x 方向的标准偏差。如果为 0,则从 kernel_size 计算。

注意

高斯模糊是一种线性滤波器,它使用高斯核来平滑图像。

高斯核是一个钟形曲线,其中心权重最大,边缘权重逐渐减小。

kernel_size 越大,模糊效果越强。

sigmaX 越大,模糊效果越明显。

高斯模糊可能会导致图像质量下降,尤其是边缘和细节丢失。

4、完整代码:

  1. #include <iostream>
  2. #include "opencv2/core.hpp"
  3. #include <opencv2/imgcodecs.hpp>
  4. #include <opencv2/highgui.hpp>
  5. #include <opencv2/core/mat.hpp>
  6. #include <opencv2/imgproc.hpp>
  7. using namespace std;
  8. using namespace cv;
  9. int main(){
  10. Mat image;
  11. image = imread("firefox.png"); //imread()读取图片
  12. if(!image.empty()){
  13. namedWindow("image", cv::WINDOW_NORMAL);
  14. imshow("image",image); //imshow展示图片,前面为展示名,后面为图片。
  15. resizeWindow("image", 640, 480);
  16. waitKey(0);
  17. }
  18. // destroyAllWindows();
  19. Mat resize_image;
  20. resize(image, resize_image, Size(), 1, 0.5); //resize()改变大小 前为高度 后为宽度
  21. if(!resize_image.empty()){
  22. namedWindow("resize", cv::WINDOW_NORMAL);
  23. imshow("resize",resize_image);
  24. resizeWindow("resize", 640, 480);
  25. waitKey(0);
  26. }
  27. imwrite("resize.png",resize_image); //imwrite(文件名,图片)写入文件 需要指定扩展名,否则exception
  28. // destroyAllWindows();
  29. Mat rotated_image;
  30. double angle = 90; //旋转角度
  31. Point2f center(image.cols / 2.0, image.rows / 2.0); //获取旋转中心
  32. Mat rotation_matix = getRotationMatrix2D(center, angle, 0.5); //getRotationMatrix2D()计算旋转矩阵 参数:旋转中心、旋转角度、放大倍数
  33. warpAffine(image, rotated_image, rotation_matix, image.size()); //warpAffine旋转图片 参数:原图、目标图片、旋转矩阵、生成图片的大小
  34. if(!rotated_image.empty()){
  35. namedWindow("rotate", cv::WINDOW_NORMAL);
  36. imshow("rotate",rotated_image);
  37. resizeWindow("rotate", 640, 480);
  38. waitKey(0);
  39. }
  40. imwrite("rotate.png",rotated_image);
  41. // destroyAllWindows();
  42. Mat translated_image;
  43. float tx = float(image.rows) / 4; //平移距离 1/4
  44. float ty = float(image.cols) / 4; //平移距离 1/4
  45. float warp_values[] = { 1.0, 0.0, tx, 0.0, 1.0, ty }; //构建平移矩阵
  46. Mat translation_matrix = Mat(2, 3, CV_32F, warp_values); //构建平移矩阵
  47. warpAffine(image, translated_image, translation_matrix, image.size()); //warpAffine平移图片
  48. if(!translated_image.empty()){
  49. namedWindow("translated", cv::WINDOW_NORMAL);
  50. imshow("translated",translated_image);
  51. resizeWindow("translated", 640, 480);
  52. waitKey(0);
  53. }
  54. imwrite("translated.png",translated_image);
  55. destroyAllWindows();
  56. Mat flipped_image_row;
  57. Mat flipped_image_col;
  58. flip(image, flipped_image_row, 1); //水平翻转
  59. flip(image, flipped_image_col, 0); //垂直翻转
  60. imshow("row",flipped_image_row);
  61. imshow("col",flipped_image_col);
  62. imshow("image",image);
  63. waitKey(0);
  64. destroyAllWindows();
  65. Mat blurred_image;
  66. GaussianBlur(image, blurred_image, cv::Size(99,99), 0);
  67. imshow("blurred_image",blurred_image);
  68. waitKey(0);
  69. destroyAllWindows();
  70. return 0;
  71. }

简单四宫格:

  1. #include <opencv2/core/mat.hpp>
  2. #include <opencv2/imgcodecs.hpp>
  3. #include <opencv2/highgui.hpp>
  4. #include <opencv2/imgproc.hpp>
  5. using namespace cv;
  6. int main(){
  7. Mat image = imread("firefox.png");
  8. // Mat image_45;
  9. Mat image_90;
  10. Mat image_180;
  11. Mat image_270;
  12. // double angle_45 = 45;
  13. double angle_90 = 90;
  14. double angle_180 = 180;
  15. double angle_270 = 270;
  16. Point2f center(image.cols / 2.0, image.rows / 2.0);
  17. // Mat rotation_matix_45 = getRotationMatrix2D(center, angle_45, 1.0);
  18. // warpAffine(image, image_45, rotation_matix_45, image.size());
  19. Mat rotation_matix_90 = getRotationMatrix2D(center, angle_90, 1.0);
  20. warpAffine(image, image_90, rotation_matix_90, image.size());
  21. Mat rotation_matix_180 = getRotationMatrix2D(center, angle_180, 1.0);
  22. warpAffine(image, image_180, rotation_matix_180, image.size());
  23. Mat rotation_matix_270 = getRotationMatrix2D(center, angle_270, 1.0);
  24. warpAffine(image, image_270, rotation_matix_270, image.size());
  25. Mat row_1;
  26. Mat row_2;
  27. Mat image_4x4;
  28. hconcat(std::vector<cv::Mat>{image, image_90},row_1); //横向拼接
  29. hconcat(std::vector<cv::Mat>{image_270, image_180},row_2); //纵向拼接
  30. vconcat(std::vector<cv::Mat>{row_1, row_2},image_4x4);
  31. imshow("4x4",image_4x4);
  32. waitKey(0);
  33. destroyAllWindows();
  34. return 0;
  35. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/881456
推荐阅读
相关标签
  

闽ICP备14008679号