opencv
- 一图像通道的分离和合并
- 二.图像色彩改变
- 三.简单形状识别
- 1.灰度处理
- 2.高斯滤波
- 3.边缘检测
- 4.膨胀
- 三.像素点统计
- 四.多边形的绘制和填充
- 五.鼠标操作与响应(截图)
- 六.图像的像素转换和归一化
- 七.视频文件摄像头使用
- 八.视频的处理与保存
- 九.图像直方图
- 十.卷积核
一图像通道的分离和合并
split函数,分离通道。merge函数合并通道,merge有两个版本分别对应vector的和数组的。mixChannels可以直接进行通道混合。
二.图像色彩改变
三.简单形状识别
识别详解1
识别详解2
1.灰度处理
cvtColor(img, imgGray,COLOR_BGR2GRAY, 0);
2.高斯滤波
传送门(高斯滤波)
3.边缘检测
4.膨胀
三.像素点统计
方差
四.多边形的绘制和填充
绘制和填充
五.鼠标操作与响应(截图)
void setMousecallback(const string& winname, MouseCallback onMouse, void * userdata=0)
winname:窗口的名字
onMouse:鼠标响应函数,回调函数。指定窗口里每次鼠标时间发生的时候,被调用的函数指针。 这个函数的 原型应该为void on_Mouse(int event, int x, int y, int flags, void * param);
userdate:传给回调函数的参数
void on_Mouse(int event, int x, int y, int flags, void * param);
event是 CV_EVENT_ * 变量之一
x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系)
flags是CV_EVENT_FLAG的组合, param是用户定义的传递到setMouseCallback函数调用的参数。
event
flag
截取任意图形
boundingRect只有一个参数即传vector,vector里是点集(不能有斜度)。minAreaRect可以有斜度。
简易的截图工具(按中键可以转换成三角形)ps:滑到外面会导致系统t终止可以自行修正
//截图
Point sp(-1, -1);
Point ep(-1, -1);
Point dp(-1, -1);
Mat tmp;
int ret;
void on_Mouse(int event, int x, int y, int flags, void* param)
{
Mat img = *(Mat*)param;
if (event == EVENT_MBUTTONDOWN)//按住中间
{
if (ret == 1) ret = 0;
else ret = 1;
}
if (event == EVENT_LBUTTONDOWN)//按下左键
{
sp.x = x;
sp.y = y;
}
else if (event == EVENT_LBUTTONUP)//松开左键
{
ep.x = x;
ep.y = y;
int dx = abs(ep.x - sp.x);
int dy = abs(ep.y - sp.y);
dp.x = sp.x;
dp.y = y;
vector<Point>p;
p.push_back(sp);
p.push_back(ep);
p.push_back(dp);
if (ret == 0)
{
Rect box(sp.x, sp.y, dx, dy);
rectangle(img, box, Scalar(0, 0, 255));
imshow("ROI区域", img(box));
imshow("鼠标绘制", img);
}
else if (ret == 1)
{
Rect ret = boundingRect(p);
polylines(img,p, 1, Scalar(0, 255, 255));
imshow("ROI区域", img(ret));
imshow("鼠标绘制", img);
}
sp.x = 0, sp.y = 0;
ep.x = 0, ep.y = 0;
dp.x = 0, dp.y = 0;
}
else if (event == EVENT_MOUSEMOVE)//移动鼠标
{
ep.x = x;
ep.y = y;
int dx = abs(ep.x - sp.x);
int dy = abs(ep.y - sp.y);
dp.x = sp.x;
dp.y = y;
vector<Point>p;
p.push_back(sp);
p.push_back(ep);
p.push_back(dp);
tmp.copyTo(img);
if (ret==0&&sp.x > 0 && sp.y > 0)
{
rectangle(img, Rect(sp.x, sp.y, dx, dy), Scalar(0, 0, 255));
imshow("鼠标绘制", img);
}
else if (ret == 1&&sp.x>0&&sp.y>0)
{
polylines(img, p, 1, Scalar(0, 255, 255));
imshow("鼠标绘制", img);
}
}
}
int main()
{
Mat img=imread("C:/Users/ASUS/Pictures/Screenshots/建筑物1.png");
string p("鼠标绘制");
namedWindow(p);
setMouseCallback(p,on_Mouse,&img);
imshow("鼠标绘制", img);
tmp = img.clone();
//namedWindow("bin");
//imshow("bin", bin);
waitKey();
return 0;
}
六.图像的像素转换和归一化
一个函数convertTO,可以将图片转换成其他类型,这里归一化是将像素点调到0-1之间,所以必须先将图片转换成浮点数存储。
七.视频文件摄像头使用
八.视频的处理与保存
int main()
{
VideoCapture capture("C:/Users/ASUS/Videos/Captures/风景1.mp4");
if (!capture.isOpened())//判断是否打开成功
{
cout << "open fail" << endl;
return -1;
}
//获取视频属性
int wid = capture.get(CAP_PROP_FRAME_WIDTH);//读取宽
int hight = capture.get(CAP_PROP_FRAME_HEIGHT);//读取高
int count = capture.get(CAP_PROP_FRAME_COUNT);//读取总帧数
double fps = capture.get(CAP_PROP_FPS);//读取一秒多少帧
cout << wid << "宽" << endl;
cout << hight << "高" << endl;
cout << count << "count" << endl;
cout << fps << "fps" << endl;
//保存视频
//1.保存位置 2.保存代码段 3.fps 4.尺寸 5.颜色是否一致
//和下面的write搭配使用
VideoWriter writer("C:/Users/ASUS/Videos/Captures/test.mp4",capture.get(CAP_PROP_FOURCC),fps,Size(wid,hight),true);
//播放视频
Mat fram;
while (1)
{
capture >> fram;//读取视频帧
if (fram.empty())//判断是否到结尾
break;
imshow("fram", fram);
writer.write(fram);
int c = waitKey(1);//等待25ms
if (c == 27) break;
}
capture.release();
writer.release();
return 0;
}
九.图像直方图
参考博客
int main()
{
Mat img = imread("C:/Users/ASUS/Pictures/Screenshots/建筑物1.png");
//三通道分离
vector<Mat> bgr_plane;
split(img, bgr_plane);
//定义参数变量
const int channels[1] = { 0 };
const int bins[1] = { 256 };
float hranges[2] = { 0,255 };
const float* ranges[1] = { hranges };
Mat b_hist;
Mat g_hist;
Mat r_hist;
//计算Blue, Green, Redi通道的直方图
calcHist(&bgr_plane[0],1,0,Mat(),b_hist,1,bins,ranges);
calcHist(&bgr_plane[1],1,0,Mat(),g_hist,1,bins,ranges);
calcHist(&bgr_plane[2],1,0,Mat(),r_hist,1,bins,ranges);
//显示直方图
int hist_w = 512;
int hist_h = 400;
int bin_w = cvRound((double)hist_w / bins[0]);
Mat histImage = Mat:: zeros(hist_h, hist_w, CV_8UC3);
//归一化直方图数据
normalize(b_hist,b_hist,0,histImage.rows,NORM_MINMAX,- 1,Mat());
normalize(g_hist,g_hist,0,histImage.rows,NORM_MINMAX,- 1,Mat());
normalize(r_hist,r_hist,0,histImage.rows,NORM_MINMAX,- 1,Mat());
//绘制直方图曲线
for (int i = 1; i < bins[0]; i++)
{
line(histImage, Point(bin_w * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
Point(bin_w * (i), hist_h - cvRound(b_hist.at<float>(i))), Scalar(255, 0, 0), 2, 8, 0);
line(histImage, Point(bin_w * (i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),
Point(bin_w * (i), hist_h - cvRound(g_hist.at<float>(i))), Scalar(0, 255, 0), 2, 8, 0);
line(histImage, Point(bin_w * (i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),
Point(bin_w * (i), hist_h - cvRound(r_hist.at<float>(i))), Scalar(0, 0, 255), 2, 8, 0);
// 显示直方图
}
namedWindow("Histogram Demo", WINDOW_AUTOSIZE);
imshow("Histogram Demo", histImage);
waitKey();
return 0;
}
十.卷积核
下面的卷积核就是求出3*3方格里的均值再放入中心点,依次往后移动。这样只有最外层的格子不能被处理,对于最外层一般有丢弃和填充两种方法。这种均值操作会导致图像的信息丢失,更加模糊。