Opencv4 c/c++学习笔记(一)

Opencv4 c/c++学习笔记(一)

初入计算机视觉,做做笔记
为了便于运用和记忆,注释较为繁琐嘻嘻
学习参考资料:opencv4官网tutorial和《学习OpenCV3》

显示一张图片

#include "opencv2/opencv.hpp"  
//包含所有模块的头文件,占用运行内存缺点
int main()
{
    //地址用‘/’,根据载入的图片(多格式)申请图像需要的内存
    //cv::Mat图像在生命周期结束时自动释放
    cv::Mat img=cv::imread("C:/Users/16242/Desktop/1.jpg");
    //,cv::ImreadModes::IMREAD_UNCHANGED);
/*
Mat cv::imread	(	const String & 	filename,
int 	flags = IMREAD_COLOR 
)		
filename	Name of file to be loaded.
flags	Flag that can take values of cv::ImreadModes
*/

    if(img.empty()) return -1;//出错
/*
bool cv::Mat::empty	(		)	const
Returns true if the array has no elements.
*/
    cv::namedWindow("ALINA");
    //,cv::WindowFlags::WINDOW_AUTOSIZE);
//"中文"乱码
/*
void cv::namedWindow	(	const String & 	winname,
int 	flags = WINDOW_AUTOSIZE 
)	
winname	Name of the window in the window caption that may be used as a window identifier.
flags	Flags of the window. The supported flags are: (cv::WindowFlags)
*/
    cv::imshow("ALINA",img);
/*
void cv::imshow	(	const String & 	winname,
InputArray 	mat 
)	
winname	Name of the window.
mat	Image to be shown.
若窗口不存在,会自动调用cv::namedWindow()新建一个
*/
    cv::waitKey(5000);
/*
int cv::waitKey	(	int 	delay = 0	)	
delay	Delay in milliseconds. 0 is the special value that means "forever".
                               0-press any key can exit the program
The function only works if there is at least one HighGUI window created and the window is active.
*/
    cv::destroyWindow("ALINA");
    return 0;

}
/*一些优化
命名空间using namespace cv;
代替cv::

#include "opencv2/highgui/highgui.hpp"
代替
包含全部模块头文件的#include "opencv2/opencv.hpp"
*/

显示视频

其中
    VideoCapture cap;
    cap.open("C:/Users/16242/Desktop/1.mp4");
遇到bug??未解决
[ERROR:0] global F:\VScode\openCV\sources\modules\videoio\src\backend_plugin.cpp (227) PluginBackend Video I/O: wrong OpenCV minor version used by plugin 'FFmpeg OpenCV Video I/O plugin': 4.1, OpenCV version is '4.2.0' 
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
int main()
{
    VideoCapture cap;
    cap.open(0);   //前置摄像头
    //cap.open("C:/Users/16242/Desktop/1.mp4");//有bug???
/*
virtual bool cv::VideoCapture::open	(	const String & 	filename,
int 	apiPreference = CAP_ANY 
)	
return true if the file has been successfully opened
*/
    Mat img;
    namedWindow("ALINA");
    for(;;)
    {
        cap>>img;
        if(img.empty()) break;
        imshow("ALINA",img);
        if(waitKey(33)>=0) break;  //按键中断
    }
    return 0;

}

在这里插入图片描述在这里插入图片描述

Plus
视频跳转,添加进度条:见《学习OpenCV3》P56

平滑处理图像

//对图像的平滑处理,高斯核或其他核卷积 减小图像的信息量
#include "opencv2/opencv.hpp"
using namespace cv;
int main()
{
    Mat in=cv::imread("C:/Users/16242/Desktop/1.jpg");
    namedWindow("input");
    namedWindow("output");
    imshow("input",in);
    Mat out;
    //Do the smoothing
    //Could use GaussianBlur(),blur(),medianBlur() or bilateralFilter()
    GaussianBlur(in,out,Size(5,5),3,3);
/*  
void cv::GaussianBlur	(	InputArray 	src,
OutputArray 	dst,
Size 	ksize,
double 	sigmaX,
double 	sigmaY = 0,
int 	borderType = BORDER_DEFAULT 
)	


src	input image; the image can have any number of channels, which are processed independently, but the depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
dst	output image of the same size and type as src.
ksize	Gaussian kernel(内核) size. ksize.width and ksize.height can differ but they both must be positive and odd.(奇数) Or, they can be zero's and then they are computed from sigma.
sigmaX	Gaussian kernel standard deviation in X direction.
sigmaY	Gaussian kernel standard deviation in Y direction; if sigmaY is zero, it is set to be equal to sigmaX, if both sigmas are zeros, they are computed from ksize.width and ksize.height, respectively (see getGaussianKernel for details); to fully control the result regardless of possible future modifications of all this semantics, it is recommended to specify all of ksize, sigmaX, and sigmaY.
borderType	pixel extrapolation method, see BorderTypes
*/
    imshow("output",out);
    waitKey();
    return 0;

}

在这里插入图片描述

关于高斯内核各参数效果,下文大佬讲解详细(用轨迹条观察)
https://blog.csdn.net/qq_34374664/article/details/82257020

erode和blur

Mat srcimage=imread("/home/alina/opencv_ros_test/src/1.jpg");
imshow("原始图像",srcimage);
 if(srcimage.empty()) printf("read image error.");
//****************图形腐蚀*************
 Mat element =getStructuringElement(MORPH_RECT,Size(30,15));
 //getStructuringElement函数返回值为指定形状和尺寸的结构元素(内核矩阵)
 //The function constructs and returns the structuring element that can be further passed to erode, dilate or morphologyEx. But you can also construct an arbitrary binary mask yourself and use it as the structuring element.

 Mat image1;
 erode(srcimage,image1,element);
 //原始,输出,结构元素
 imshow("腐蚀之后",image1);
 //***************图像模糊**************
  Mat image2;
 blur(srcimage,image2,Size(7,7));
 //均值滤波
 imshow("模糊之后",image2);

 waitKey(0);
 return 0;

在这里插入图片描述

//定义轨迹条名字
char TrackBarName[20],const int MaxValue = 11;
sprintf(TrackBarName, "XXX", MaxValue);
//创建轨迹条
createTrackbar(TrackBarName, "轨迹条窗口名字", &int 轨迹条初始值, 
                MaxValue, 回调函数);

创建图像金字塔的两个函数pyrDown()和pryUp()

    pyrDown(in,out);
/*先对图像进行高斯平滑,然后再进行降采样(将图像尺寸行和列方向缩减一半)
隔行隔列删去图像中的对应行和列,失真用高斯模糊弥补
void cv::pyrDown	(	InputArray 	src,
OutputArray 	dst,
const Size & 	dstsize = Size(),
int 	borderType = BORDER_DEFAULT 
)	
src	input image.
dst	output image; it has the specified size and the same type as src.
dstsize	size of the output image.
borderType	Pixel extrapolation method, see BorderTypes (BORDER_CONSTANT isn't supported)

By default, size of the output image is computed as Size((src.cols+1)/2, (src.rows+1)/2)
*/
/*创建图像金字塔的两个函数pyrDown()和pryUp()
将降采样和平滑滤波结合在一起,对图像进行多尺度表示
需要满足
|dstsize.width * 2 - src.cols| ≤ 2;
|dstsize.height * 2 - src.rows| ≤ 2;
也就是说降采样的意思其实是把图像的尺寸缩减一半,行和列同时缩减一半。所以你指定的大小,无非就是多一行少一列的区别而已。在大多数情况下使用默认值就可了*/
	pryUp(in,out');
/*
先对图像进行升采样(将图像尺寸行和列方向增大一倍),然后再进行高斯平滑*/

在这里插入图片描述

Canny边缘检测器

//Canny()边缘检测器输出一个单通道的灰度图像
#include "opencv2/opencv.hpp"
using namespace cv;
int main()
{
    Mat img_rgb,img_gry,img_cny;
    img_rgb=cv::imread("C:/Users/16242/Desktop/1.jpg");
    namedWindow("Gray");
    namedWindow("Canny");
    cvtColor(img_rgb,img_gry,COLOR_BGR2GRAY);
/*
void cv::cvtColor	(	InputArray 	src,
OutputArray 	dst,
int 	code,
int 	dstCn = 0 
)	
code	color space conversion code (see ColorConversionCodes).
dstCn	number of channels in the destination image; if the parameter is 0, the number of the channels is derived automatically from src and code.
*/
    imshow("Gray",img_gry);
    GaussianBlur(img_gry,img_gry,Size(1,1),1,1);
    Canny(img_gry,img_cny,10,100,3,true);
/*Canny函数本身应该没有将图像降噪包含在内
void cv::Canny	(	InputArray 	image,
OutputArray 	edges,
double 	threshold1,
double 	threshold2,
int 	apertureSize = 3,
bool 	L2gradient = false 
)	
threshold1	first threshold for the hysteresis procedure.
threshold2	second threshold for the hysteresis procedure.
apertureSize	aperture size for the Sobel operator.
L2gradient	a flag, indicating whether a more accurate L2 norm =(dI/dx)2+(dI/dy)2−−−−−−−−−−−−−−−−√ should be used to calculate the image gradient magnitude ( L2gradient=true ), or whether the default L1 norm =|dI/dx|+|dI/dy| is enough ( L2gradient=false ).
*/
    imshow("Canny",img_cny);
    waitKey(0);

}

在这里插入图片描述
关于更具体的Canny边缘检测,下文大佬讲解详细
https://blog.csdn.net/saltriver/article/details/80545571

读写像素值

//Canny()边缘检测器输出一个单通道的灰度图像
#include "opencv2/opencv.hpp"
using namespace cv;
int main()
{
    Mat img;
    img=cv::imread("C:/Users/16242/Desktop/1.jpg");
    namedWindow("ALINA");

    int x=16,y=32;
    cv::Vec3b aaa=img.at<cv::Vec3b>(y,x);

/*
typedef Vec<uchar, 3> cv::Vec3b
typedef Vec<float, 3> cv::Vec3f
typedef Vec<int, 3> cv::Vec3i
typedef Vec<short, 3> cv::Vec3s
typedef Vec<ushort, 3> cv::Vec3w
typedef Vec<uchar, 3> cv::Vec3b
*/
    uchar blue=aaa[0];
    uchar green=aaa[1];
    uchar red=aaa[2];
    std::cout<<(uint)blue<<(uint)green<<(uint)red<<std::endl;
    std::cout<<(uint)img.at<uchar>(y,x);
    for(x=0;x<500;x++)
    for(y=0;y<500;y++)
    {
        img.at<uchar>(x,y)=255;  //set the pixel to 200
    }
    
    imshow("ALINA",img);
    waitKey(0);

}

在这里插入图片描述

Plus
写入avi文件:见《学习OpenCV3》P65

cv::VideoCapture capture(argv[1]);
double fps=capture.get(CAP_PROP_FPS);
cv::Size size(
    (int)capture.get(CAP_PROP_FRAME_WIDTH),
    (int)capture.get(CAP_PROP_FRAME_HEIGHT)
);
/*
virtual double cv::VideoWriter::get	(	int 	propId	)	const

propId	Property identifier from cv::VideoWriterProperties (eg. cv::VIDEOWRITER_PROP_QUALITY) or one of Additional flags for video I/O API backends
*/
cv::VideoWriter writer;
writer.open(argv[2],CAP_OPENCV_MJPEG ,fps,size); //运动-jpeg编解码器Built-in OpenCV MotionJPEG codec.
/*
virtual bool cv::VideoWriter::open	(	const String & 	filename,
int 	fourcc,
double 	fps,
Size 	frameSize,
bool 	isColor = true 
)
filename	Name of the output video file.
fourcc	4-character code of codec used to compress the frames. For example, VideoWriter::fourcc('P','I','M','1') is a MPEG-1 codec, VideoWriter::fourcc('M','J','P','G') is a motion-jpeg codec etc. List of codes can be obtained at Video Codecs by FOURCC page. FFMPEG backend with MP4 container natively uses other values as fourcc code: see ObjectType, so you may receive a warning message from OpenCV about fourcc code conversion.
fps	Framerate of the created video stream.
frameSize	Size of the video frames.
isColor	If it is not zero, the encoder will expect and encode color frames, otherwise it will work with grayscale frames (the flag is currently supported on Windows only).

*/

第一天学习finish,喝奶茶去啦
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

yikide

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

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

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

打赏作者

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

抵扣说明:

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

余额充值