OpenCV(1)基本操作、检测数量 C++

18 篇文章 9 订阅
                <h2><a id="1OpenCV__0"></a>1.OpenCV 图像加载&#xff0c;显示&#xff0c;修改和保存</h2> 
- (cv :: imread)加载图像
- (cv :: namedWindow)创建一个名为OpenCV的窗口

namedWindow(“OpenCV窗口”, 2); //值为2时,可以鼠标调整窗口大小

- (cv :: imshow)在OpenCV窗口中显示图像
- (cv :: cvtColor)将图像从BGR转换为灰度格式
- (cv :: imwrite)保存图像 imwrite(E:…/data/test.tif", result4);

1.2.图像格式:imgcodecs.hpp

文件路径:E:\Desktop\opencv\build\include\opencv2\imgcodecs.hpp

- (IMREAD_UNCHANGED(<0))按原样加载图像(包括alpha通道(如果存在)
- (IMREAD_GRAYSCALE(0))将图像作为强度加载
- (IMREAD_COLOR(> 0))以RGB格式加载图像

1.3.颜色转换码:imgproc.hpp

文件路径:E:\Desktop\opencv\sources\modules\imgproc\include\opencv2\imgproc.hpp

- (COLOR_RGB2GRAY)
- (COLOR_BGR2YUV)
- (COLOR_BGR2YCrCb)

1.4. 使用OpenCV读取图片:

例1:MyOpenCV.cpp

using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
    String imageName("../data/HappyFish.jpg");  
    if (argc > 1)   //确保从命令行获取有效的图像名称参数。否则默认拍照:HappyFish.jpg
    {
        imageName = argv[1];    //调用第一个参数(argv[1])指定的映像名称的cv::imread函数。
    }
    Mat image;  //创建一个Mat对象,它将存储加载的图像的数据。
    image = imread(imageName, IMREAD_COLOR); //读取文件,以RGB格式加载图像
    if (image.empty())                      // 检查无效输入
    {
        cout << "Could not open or find the image!无法打开或找到图像!" << std::endl;
        return -1;
    }
    namedWindow("Display window", WINDOW_AUTOSIZE); // 创建一个名为OpenCV的窗口
    imshow("Display window", image);                // 在OpenCV窗口中显示图像
    waitKey(0); // 等待窗口中的按键,窗口被显示直到用户按下一个按键
    return 0;
}

例2:MyOpenCV.cpp

#include <opencv2\opencv.hpp>
int main() 
{
	cv::Mat img = cv::imread("E:/desktop/test.jpg");//加载图像
	cv::imshow("test", img);	//在窗口中显示图像
	cv::waitKey();
	return 0;
}

执行结果:
在这里插入图片描述

1.5. 将图像从BGR转换成灰度格式

例1:MyOpenCV.cpp

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std; 
int main(int argc, char** argv)
{
	String imageName("../data/test.jpg");
	if (argc > 1)   //确保从命令行获取有效的图像名称参数。否则默认拍照:HappyFish.jpg
	{
		imageName = argv[1];    //调用第一个参数(argv[1])指定的映像名称的cv::imread函数。
	}
	Mat image;  //创建一个Mat对象,它将存储加载的图像的数据。
	image = imread(imageName, IMREAD_COLOR); //读取文件,以RGB格式加载图像
	if (image.empty())                      // 检查无效输入
	{
		cout << "Could not open or find the image!无法打开或找到图像!" << std::endl;
		return -1;
	}
	Mat gray_image; //创建一个Mat对象,它将存储加载的图像的数据。
	cvtColor(image, gray_image, COLOR_BGR2GRAY);//将图片从BGR转换为灰度格式
	imwrite("../data/test1.jpg", gray_image);//保存转换后的图片
	namedWindow(imageName, WINDOW_AUTOSIZE); // 创建一个名为OpenCV的窗口
	namedWindow("gray_image", WINDOW_AUTOSIZE); // 创建一个名为OpenCV的窗口
	imshow(imageName, image);       // 在OpenCV窗口中显示图像
	imshow("gray_image", gray_image);   // 在OpenCV窗口中显示图像
	waitKey(0); // 等待窗口中的按键,窗口被显示直到用户按下一个按键
	return 0;
}

执行结果:
在这里插入图片描述

2.拍照、读取视频、保存视频

2.1. c++使用OpenCV读取视频:

#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
	//读取视频或摄像头
	VideoCapture capture(0);
	while (true)
	{
		Mat frame;
		capture >> frame;
		imshow("读取视频", frame);
		waitKey(30);	//延时30
	}
	return 0;
}

执行结果:
在这里插入图片描述

2.2. 拍照

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
//工程目录下的temp文件夹里,与.sln同级的temp文件
string writePath = "../data/";
int main(int argc, char** argv) {
	VideoCapture capture(0);
	string name;
	namedWindow("hello", WINDOW_AUTOSIZE);
	int i = 0;
	while (1) {
		Mat frame;
		capture >> frame;
		if (32 == waitKey(20)) {			//空格拍照
			name = writePath + to_string(i) + ".jpg";
			imwrite(name, frame);
			cout << name << endl;
			i++;
		}
		if (97 == waitKey(10)) {			//'a'退出
			break;
		}
		imshow("hello", frame);
		imwrite("E:../data/test.tif", frame);//保存图像
	}
	//waitKey(0);
}

按空格拍照

2.3.批量保存

char file_img[100];
String num[11] = { " ","1","2","3","4","5","6","7","8","9","0"};
    for (int i = 1; i <= 10; i++)
    {
        ...
        //Mat roi = src(rect);
        sprintf_s(file_img, "../data/number/%s.jpg",num[i]);// 给file_img赋值:1.jpg 2.jpg等
        imwrite(file_img, roi);
    }

3.OpenCV实践

3.1.检测数量

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
    Mat src = imread("./image/test14.jpg");
    //medianBlur(src, src,5);//中值滤波,去除椒盐噪声
    imshow("src", src);
    Mat src_gray, binary;
    cvtColor(src, src_gray, COLOR_BGR2GRAY);
    threshold(src_gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);//颜色单一时,使用THRESH_TRIANGLE比OTSU好
    imshow("binary", binary);
    //形态学操作
    Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
    dilate(binary, binary, kernel, Point(-1, -1), 2.9);
    //距离变换
    Mat dist;
    bitwise_not(binary, binary);//取反
    distanceTransform(binary, dist, DIST_L2, 3);
    normalize(dist, dist, 0, 1.0, NORM_MINMAX);
    imshow("dist", dist);
    //阈值化二值分割
    threshold(dist, dist,0.4,1.0,THRESH_BINARY);//对距离进行筛选,去除边缘部分
    normalize(dist, dist, 0, 255, NORM_MINMAX);
    Mat dist_8U;
    dist.convertTo(dist_8U, CV_8U);
    adaptiveThreshold(dist_8U, dist_8U, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 85, 0.0);//自适应阈值,代替上面的阈值操作
    //形态学操作,使得断开部分连接
    kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
    dilate(dist_8U, dist_8U, kernel, Point(-1, -1), 3);
    imshow("dist_8U", dist_8U);
    // 连通区域计数
    vector<vector<Point>> contours;
    findContours(dist_8U, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    // draw result
    Mat markers = Mat::zeros(src.size(), CV_8UC3);
    RNG rng(12345);
    for (size_t t = 0; t < contours.size(); t++) {
        drawContours(markers, contours, static_cast<int>(t), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)),
            -1, 8, Mat());
    }
    printf("number of corns : %d", contours.size());
    imshow("Final result", markers);
    waitKey(0);
    return 0;
}

执行结果:
在这里插入图片描述
在这里插入图片描述

4.(cv :: createTrackbar)滑动条

CV_EXPORTS int createTrackbar(const String& trackbarname, const String& winname,
                              int* value, int count,
                              TrackbarCallback onChange = 0,
                              void* userdata = 0);
  • trackbarname:轨迹条名。
  • winname:窗口的名称,它将被用作创建的轨迹栏的父窗口。
  • value:一个指向整型的指针,表示滑块的位置。并且在创建时,滑块的初始位置就是该变量当前的值。
  • count:表示滑块可以达到的最大位置的值。滑块最小的位置的值始终为0。
  • onChange:首先注意他有默认值0。这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。并且这个函数的原型必须为void fun(int,void*)其中第一个参数是轨迹条的位置,第二个参数是用户数据(看下面的第六个参数)。如果回调是NULL指针,表示没有回调函数的调用,仅第三个参数value有变化。
  • userdata:它也有默认值0。这个参数是用户传给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value实参是全局变量的话,完全可以不去管这个userdata参数。
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
int value1 = 10;		//滑动条的初始值
Mat image, image1;
static void on_track1(int, void*);	//回调函数
int main()
{
	//读入图像
	image = imread("./image/test2.jpg"); 
	namedWindow("双边滤波", 2);		//值为2时,可以鼠标调整窗口大小
	//创建滑动条
	createTrackbar("孔径的线性尺寸", "双边滤波", &value1, 50, on_track1);
	on_track1(value1, 0);
	waitKey();
	return 1;
}
static void on_track1(int, void*)
{
	bilateralFilter(image, image1, value1, value1 * 2, value1 / 2);
	imshow("双边滤波", image1);
}

执行结果:
在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~晓广~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值