第一章 图像编程入门

1.3 装载、显示和存储图像

1、基本原理

本小节介绍OpenCV处理图像的基本操作,包括从文件中装载输入的图像、在窗口中显示图像和保存处理后的图像。

2、代码实现

通过实际的代码实现,可以初步了解OpenCV的工作过程与实现效果,从直观上认识OpenCV的处理过程。

/**
* 书名:《OpenCV计算机视觉编程攻略(第3版)》
* 日期:20210325
* 备注:测试例子
*/
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <cassert>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

int main(int argc, char* argv[])
{
	// 1、加载原图像
	cv::Mat image = cv::imread("images/cow.jpg");
	cv::Mat result;
	
	// 2、显示原图
	cv::namedWindow("original");
	cv::imshow("original", image);

	// 3、处理图像(水平翻转)
	cv::flip(image, result, 0);
	
	// 4、显示结果图像
	cv::namedWindow("result");
	cv::imshow("result", result);

	// 5、保存结果图像
	cv::imwrite("output/image_flip.png", result);

	// 6、等待键盘输入
	cv::waitKey(0);
	
	return 0;
}

3、验证结果

原图像:

计算机视觉教程 计算机视觉教程第三版pdf_计算机视觉教程


结果图:

计算机视觉教程 计算机视觉教程第三版pdf_Image_02

1.4 深入了解cv::Mat

1、基本原理

数字图像,其实就是数学中的矩阵,由像素点构成,一般分为单通道的灰度图和多通道的彩色图,对于OpenCV的数据存储方式,彩色图像由三通道BGR构成(与通常的RGB格式不同)。在OpenCV中,图像由从cv::Mat的数据结构管理,常用属性有宽度、高度、通道数等,以及很多实用的图像处理方法。

2、代码实现

/**
* 书名:《OpenCV计算机视觉编程攻略(第3版)》
* 日期:20210326
* 备注:测试例子
*/
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>

cv::Mat function()
{
	cv::Mat image(500, 500, CV_8U, 50);

	return image;
}

int main(int argc, char* argv[])
{
	// 创建新图象
	cv::Mat image1(240, 320, CV_8U, 100);
	cv::imshow("original", image1);
	cv::waitKey(0);

	// 重新创建
	image1.create(200, 200, CV_8U);
	image1 = 200;
	cv::imshow("Image", image1);
	cv::waitKey(0);

	// 创建一个Red图像
	cv::Mat image2(cv::Size(320, 240), CV_8UC3);
	image2 = cv::Scalar(0, 0, 255);
	
	cv::imshow("Image", image2);
	cv::waitKey(0);

	// 加载图像
	cv::Mat image3 = cv::imread("images/cow.jpg");

	// 通过赋值方式,新图象引用右值图像
	cv::Mat image4(image3);
	image1 = image3;

	// 通过clone方式,新图象拥有独立的图像数据存储空间
	image3.copyTo(image2);
	cv::Mat image5 = image3.clone();

	// 测试上述结论
	cv::flip(image3, image3, 0);

	cv::imshow("Image 3", image3);
	cv::imshow("Image 1", image1);
	cv::imshow("Image 2", image2);
	cv::imshow("Image 4", image4);
	cv::imshow("Image 5", image5);
	cv::waitKey(0);

	// 验证图像变量的作用域
	cv::Mat gray = function();
	cv::imshow("Image", gray);
	cv::waitKey(0);

	// 灰度图像的读入方法
	image1 = cv::imread("images/many_cow.jpg", IMREAD_GRAYSCALE);
	image1.convertTo(image2, CV_32F, 1 / 255.0, 0.0);
	cv::imshow("image", image2);
	cv::waitKey(0);

	return 0;
}

3、验证结果

计算机视觉教程 计算机视觉教程第三版pdf_#include_03

1.5 定义感兴趣区域

1、基本原理

使得目标图像在某个特定的区域起作用,也就是一个感兴趣区域。其中,注意无掩膜与有掩膜的区别。

2、代码实现

/**
* 书名:《OpenCV计算机视觉编程攻略(第3版)》
* 日期:20210326
* 备注:测试例子
*/
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    // 加载目标图像
    Mat image = imread("images/cow.jpg");
    imshow("Image", image);
    
    // 加载logo
    Mat logo = imread("images/logo2.jpg");
    
    // 感兴趣区域
    Mat imageROI(image, cv::Rect(image.cols - logo.cols, image.rows - logo.rows, logo.cols, logo.rows));
    
    // 融合logo
    logo.copyTo(imageROI, logo);
    
    imshow("imageROI", image);
    imwrite("output/imageROI2.jpg", image);  //保存图片
    waitKey(0);
    return 0;
}

3、验证结果

(1)无掩膜

计算机视觉教程 计算机视觉教程第三版pdf_OpenCV_04

(2)有掩膜

计算机视觉教程 计算机视觉教程第三版pdf_OpenCV_05

附录

① 文中实例取自著作《OpenCV计算机视觉编程攻略(第3版)》,以此为主题进行模仿学习,并不用于商业目的;
② 文中实例的IDE基于UBUNTU20.04环境,其中OpenCV的配置攻略可参考其他优秀作者的博客,此处不再赘述;
③ 第一次写博客,后续会持续更新,望亲爱的读者积极提意见,不胜感激~~