图像腐蚀
| #include <opencv2/highgui/highgui.hpp> |
| #include <opencv2/imgproc/imgproc.hpp> |
| using namespace cv; |
| int main() |
| { |
| Mat srclmage = imread("G:\\QQ图片20190428194331.jpg"); |
| imshow("[ 原图 ] ",srclmage); |
| |
| Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); |
| Mat dstlmage; |
| erode(srclmage, dstlmage, element); |
| |
| imshow ("[ 效果图 ] ", dstlmage); |
| waitKey(0); |
| return 0; |
| } |
图像模糊
| #include <opencv2/highgui/highgui.hpp> |
| #include <opencv2/imgproc/imgproc.hpp> |
| using namespace cv; |
| int main() |
| { |
| Mat srclmage = imread("G:\\QQ图片20190428194331.jpg"); |
| imshow("[ 原图 ] ",srclmage); |
| |
| Mat dstlmage; |
| blur(srclmage, dstlmage, Size(7, 7)); |
| imshow ("[ 效果图 ] ", dstlmage); |
| waitKey(0); |
| return 0; |
| } |
canny边缘检测
| #include<opencv2/opencv.hpp> |
| #include <opencv2/imgproc/imgproc.hpp> |
| using namespace cv; |
| int main() |
| { |
| Mat srcImage = imread("G:\\QQ图片20190428194331.jpg"); |
| imshow("[ 原图 ] ",srcImage); |
| Mat dstImage, edge, grayImage; |
| |
| dstImage.create(srcImage.size(), srcImage.type()); |
| |
| cvtColor(srcImage, grayImage, CV_BGR2GRAY); |
| |
| |
| |
| |
| blur(grayImage, edge, Size(3, 3)); |
| |
| Canny(edge, edge, 3, 9, 3); |
| |
| imshow ("[ 效果图 ] ", edge); |
| waitKey(0); |
| return 0; |
| } |

读取视频
| #include<opencv2\opencv.hpp> |
| using namespace cv; |
| int main() |
| { |
| |
| VideoCapture capture("G:\\视觉资料\\【OpenCV3版】《OpenCV3编程入门》书本配套源代码\\【1】书本正篇程序源代码\\【1】第一章\\【6】播放视频\\6_播放视频\\1.avi "); |
| |
| while(1) |
| { |
| Mat frame; |
| capture >> frame; |
| imshow("读取视频",frame); |
| waitKey(30); |
| |
| } |
| return 0; |
| } |
canny从摄像头得到的视频
| #include<opencv2\opencv.hpp> |
| using namespace cv; |
| int main() |
| { |
| |
| VideoCapture capture(0); |
| Mat edges; |
| |
| while(1) |
| { |
| Mat frame; |
| capture >> frame; |
| cvtColor(frame, edges, CV_BGR2GRAY); |
| blur(edges, edges, Size(7, 7)); |
| Canny(edges, edges, 0, 30, 3); |
| imshow("canny后的视频",edges); |
| if(waitKey(30)>=0)break; |
| |
| } |
| return 0; |
| } |
2.1.1 彩色目标跟踪:Camshift
注意:本代码仅供学习交流所用,所有权归《OpenCV3编程入门》OpenCV3版书,请勿商用
| #include "opencv2/video/tracking.hpp" |
| #include "opencv2/imgproc/imgproc.hpp" |
| #include "opencv2/highgui/highgui.hpp" |
| #include <iostream> |
| #include <ctype.h> |
| |
| using namespace cv; |
| using namespace std; |
| |
| |
| |
| |
| |
| |
| Mat image; |
| bool backprojMode = false; |
| bool selectObject = false; |
| int trackObject = 0; |
| bool showHist = true; |
| Point origin; |
| Rect selection; |
| int vmin = 10, vmax = 256, smin = 30; |
| |
| |
| |
| |
| |
| static void onMouse(int event, int x, int y, int, void*) |
| { |
| if (selectObject) |
| { |
| selection.x = MIN(x, origin.x); |
| selection.y = MIN(y, origin.y); |
| selection.width = std::abs(x - origin.x); |
| selection.height = std::abs(y - origin.y); |
| |
| selection &= Rect(0, 0, image.cols, image.rows); |
| } |
| |
| switch (event) |
| { |
| |
| |
| |
| case EVENT_LBUTTONDOWN: |
| origin = Point(x, y); |
| selection = Rect(x, y, 0, 0); |
| selectObject = true; |
| break; |
| |
| |
| |
| case EVENT_LBUTTONUP: |
| selectObject = false; |
| if (selection.width > 0 && selection.height > 0) |
| trackObject = -1; |
| break; |
| } |
| } |
| |
| |
| |
| |
| static void ShowHelpText() |
| { |
| cout << "\n\n\t\t\t非常感谢购买《OpenCV3编程入门》一书!\n" |
| << "\n\n\t\t\t此为本书OpenCV3版的第8个配套示例程序\n" |
| << "\n\n\t\t\t 当前使用的OpenCV版本为:" << CV_VERSION |
| << "\n\n ----------------------------------------------------------------------------"; |
| |
| cout << "\n\n\t此Demo显示了基于均值漂移的追踪(tracking)技术\n" |
| "\t请用鼠标框选一个有颜色的物体,对它进行追踪操作\n"; |
| |
| cout << "\n\n\t操作说明: \n" |
| "\t\t用鼠标框选对象来初始化跟踪\n" |
| "\t\tESC - 退出程序\n" |
| "\t\tc - 停止追踪\n" |
| "\t\tb - 开/关-投影视图\n" |
| "\t\th - 显示/隐藏-对象直方图\n" |
| "\t\tp - 暂停视频\n"; |
| } |
| |
| const char* keys = |
| { |
| "{1| | 0 | camera number}" |
| }; |
| |
| |
| |
| |
| |
| int main(int argc, const char** argv) |
| { |
| ShowHelpText(); |
| |
| VideoCapture cap; |
| Rect trackWindow; |
| int hsize = 16; |
| float hranges[] = { 0,180 }; |
| const float* phranges = hranges; |
| |
| cap.open(0); |
| |
| if (!cap.isOpened()) |
| { |
| cout << "不能初始化摄像头\n"; |
| } |
| |
| namedWindow("Histogram", 0); |
| namedWindow("CamShift Demo", 0); |
| setMouseCallback("CamShift Demo", onMouse, 0); |
| createTrackbar("Vmin", "CamShift Demo", &vmin, 256, 0); |
| createTrackbar("Vmax", "CamShift Demo", &vmax, 256, 0); |
| createTrackbar("Smin", "CamShift Demo", &smin, 256, 0); |
| |
| Mat frame, hsv, hue, mask, hist, histimg = Mat::zeros(200, 320, CV_8UC3), backproj; |
| bool paused = false; |
| |
| for (;;) |
| { |
| if (!paused) |
| { |
| cap >> frame; |
| if (frame.empty()) |
| break; |
| } |
| |
| frame.copyTo(image); |
| |
| if (!paused) |
| { |
| cvtColor(image, hsv, COLOR_BGR2HSV); |
| |
| if (trackObject) |
| { |
| int _vmin = vmin, _vmax = vmax; |
| |
| inRange(hsv, Scalar(0, smin, MIN(_vmin, _vmax)), |
| Scalar(180, 256, MAX(_vmin, _vmax)), mask); |
| int ch[] = { 0, 0 }; |
| hue.create(hsv.size(), hsv.depth()); |
| mixChannels(&hsv, 1, &hue, 1, ch, 1); |
| |
| if (trackObject < 0) |
| { |
| Mat roi(hue, selection), maskroi(mask, selection); |
| calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges); |
| |
| normalize(hist, hist, 0, 255, NORM_MINMAX); |
| |
| |
| |
| trackWindow = selection; |
| trackObject = 1; |
| |
| histimg = Scalar::all(0); |
| int binW = histimg.cols / hsize; |
| Mat buf(1, hsize, CV_8UC3); |
| for (int i = 0; i < hsize; i++) |
| buf.at<Vec3b>(i) = Vec3b(saturate_cast<uchar>(i*180. / hsize), 255, 255); |
| |
| |
| cvtColor(buf, buf, COLOR_HSV2BGR); |
| |
| |
| |
| for (int i = 0; i < hsize; i++) |
| { |
| int val = saturate_cast<int>(hist.at<float>(i)*histimg.rows / 255); |
| rectangle(histimg, Point(i*binW, histimg.rows), |
| Point((i + 1)*binW, histimg.rows - val), |
| Scalar(buf.at<Vec3b>(i)), -1, 8); |
| } |
| } |
| |
| calcBackProject(&hue, 1, 0, hist, backproj, &phranges); |
| backproj &= mask; |
| RotatedRect trackBox = CamShift(backproj, trackWindow, |
| |
| |
| TermCriteria(TermCriteria::EPS | TermCriteria::COUNT, 10, 1)); |
| |
| |
| |
| if (trackWindow.area() <= 1) |
| { |
| int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5) / 6; |
| trackWindow = Rect(trackWindow.x - r, trackWindow.y - r, |
| trackWindow.x + r, trackWindow.y + r) & |
| Rect(0, 0, cols, rows); |
| } |
| |
| if (backprojMode) |
| cvtColor(backproj, image, COLOR_GRAY2BGR); |
| |
| |
| ellipse(image, trackBox, Scalar(0, 0, 255), 3, LINE_AA); |
| |
| |
| |
| } |
| } |
| else if (trackObject < 0) |
| paused = false; |
| |
| if (selectObject && selection.width > 0 && selection.height > 0) |
| { |
| Mat roi(image, selection); |
| bitwise_not(roi, roi); |
| } |
| |
| imshow("CamShift Demo", image); |
| imshow("Histogram", histimg); |
| |
| char c = (char)waitKey(10); |
| if (c == 27) |
| break; |
| switch (c) |
| { |
| case 'b': |
| backprojMode = !backprojMode; |
| break; |
| case 'c': |
| trackObject = 0; |
| histimg = Scalar::all(0); |
| break; |
| case 'h': |
| showHist = !showHist; |
| if (!showHist) |
| destroyWindow("Histogram"); |
| else |
| namedWindow("Histogram", 1); |
| break; |
| case 'p': |
| paused = !paused; |
| break; |
| default: |
| ; |
| } |
| } |
| |
| return 0; |
| } |
| |
9_用光流法进行运动目标检测
| |
| |
| |
| #include <opencv2/video/video.hpp> |
| #include <opencv2/highgui/highgui.hpp> |
| #include <opencv2/imgproc/imgproc.hpp> |
| #include <opencv2/core/core.hpp> |
| #include <iostream> |
| #include <cstdio> |
| |
| using namespace std; |
| using namespace cv; |
| |
| |
| |
| |
| |
| |
| |
| |
| void tracking(Mat &frame, Mat &output); |
| bool addNewPoints(); |
| bool acceptTrackedPoint(int i); |
| |
| |
| |
| |
| string window_name = "optical flow tracking"; |
| Mat gray; |
| Mat gray_prev; |
| vector<Point2f> points[2]; |
| vector<Point2f> initial; |
| vector<Point2f> features; |
| int maxCount = 500; |
| double qLevel = 0.01; |
| double minDist = 10.0; |
| vector<uchar> status; |
| vector<float> err; |
| |
| |
| |
| |
| |
| static void help() |
| { |
| |
| cout <<"\n\n\t\t\t非常感谢购买《OpenCV3编程入门》一书!\n" |
| <<"\n\n\t\t\t此为本书OpenCV3版的第9个配套示例程序\n" |
| << "\n\n\t\t\t 当前使用的OpenCV版本为:" << CV_VERSION |
| <<"\n\n ----------------------------------------------------------------------------" ; |
| } |
| |
| |
| |
| |
| |
| int main() |
| { |
| |
| Mat frame; |
| Mat result; |
| |
| VideoCapture capture("1.avi"); |
| |
| help(); |
| if(capture.isOpened()) |
| { |
| while(true) |
| { |
| capture >> frame; |
| |
| if(!frame.empty()) |
| { |
| tracking(frame, result); |
| } |
| else |
| { |
| printf(" --(!) No captured frame -- Break!"); |
| break; |
| } |
| |
| int c = waitKey(50); |
| if( (char)c == 27 ) |
| { |
| break; |
| } |
| } |
| } |
| return 0; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| void tracking(Mat &frame, Mat &output) |
| { |
| |
| |
| cvtColor(frame, gray, COLOR_BGR2GRAY); |
| |
| |
| |
| frame.copyTo(output); |
| |
| |
| if (addNewPoints()) |
| { |
| goodFeaturesToTrack(gray, features, maxCount, qLevel, minDist); |
| points[0].insert(points[0].end(), features.begin(), features.end()); |
| initial.insert(initial.end(), features.begin(), features.end()); |
| } |
| |
| if (gray_prev.empty()) |
| { |
| gray.copyTo(gray_prev); |
| } |
| |
| calcOpticalFlowPyrLK(gray_prev, gray, points[0], points[1], status, err); |
| |
| int k = 0; |
| for (size_t i=0; i<points[1].size(); i++) |
| { |
| if (acceptTrackedPoint(i)) |
| { |
| initial[k] = initial[i]; |
| points[1][k++] = points[1][i]; |
| } |
| } |
| points[1].resize(k); |
| initial.resize(k); |
| |
| for (size_t i=0; i<points[1].size(); i++) |
| { |
| line(output, initial[i], points[1][i], Scalar(0, 0, 255)); |
| circle(output, points[1][i], 3, Scalar(0, 255, 0), -1); |
| } |
| |
| |
| swap(points[1], points[0]); |
| swap(gray_prev, gray); |
| |
| imshow(window_name, output); |
| } |
| |
| |
| |
| |
| |
| |
| |
| bool addNewPoints() |
| { |
| return points[0].size() <= 10; |
| } |
| |
| |
| |
| |
| |
| |
| |
| bool acceptTrackedPoint(int i) |
| { |
| return status[i] && ((abs(points[0][i].x - points[1][i].x) + abs(points[0][i].y - points[1][i].y)) > 2); |
| } |
点追踪
| #include "opencv2/video/tracking.hpp" |
| #include "opencv2/imgproc/imgproc.hpp" |
| #include "opencv2/highgui/highgui.hpp" |
| |
| #include <iostream> |
| #include <ctype.h> |
| |
| using namespace cv; |
| using namespace std; |
| |
| |
| |
| |
| |
| |
| static void help() |
| { |
| |
| cout << "\n\n\t\t\t非常感谢购买《OpenCV3编程入门》一书!\n" |
| << "\n\n\t\t\t此为本书OpenCV3版的第10个配套示例程序\n" |
| << "\n\n\t\t\t 当前使用的OpenCV版本为:" << CV_VERSION |
| << "\n\n ----------------------------------------------------------------------------"; |
| cout << "\n\n\t该Demo演示了 Lukas-Kanade基于光流的lkdemo\n"; |
| cout << "\n\t程序默认从摄像头读入视频,可以按需改为从视频文件读入图像\n"; |
| cout << "\n\t操作说明: \n" |
| "\t\t通过点击在图像中添加/删除特征点\n" |
| "\t\tESC - 退出程序\n" |
| "\t\tr -自动进行追踪\n" |
| "\t\tc - 删除所有点\n" |
| "\t\tn - 开/光-夜晚模式\n" << endl; |
| } |
| |
| Point2f point; |
| bool addRemovePt = false; |
| |
| |
| |
| |
| static void onMouse(int event, int x, int y, int , void* ) |
| { |
| |
| |
| |
| if (event == EVENT_LBUTTONDOWN) |
| { |
| point = Point2f((float)x, (float)y); |
| addRemovePt = true; |
| } |
| } |
| |
| |
| |
| |
| int main(int argc, char** argv) |
| { |
| help(); |
| |
| VideoCapture cap; |
| |
| |
| |
| |
| TermCriteria termcrit(TermCriteria::MAX_ITER | TermCriteria::EPS, 20, 0.03); |
| Size subPixWinSize(10, 10), winSize(31, 31); |
| |
| const int MAX_COUNT = 500; |
| bool needToInit = false; |
| bool nightMode = false; |
| |
| |
| cap.open(0); |
| |
| if (!cap.isOpened()) |
| { |
| cout << "Could not initialize capturing...\n"; |
| return 0; |
| } |
| |
| namedWindow("LK Demo", 1); |
| setMouseCallback("LK Demo", onMouse, 0); |
| |
| Mat gray, prevGray, image; |
| vector<Point2f> points[2]; |
| |
| for (;;) |
| { |
| Mat frame; |
| cap >> frame; |
| if (frame.empty()) |
| break; |
| |
| frame.copyTo(image); |
| cvtColor(image, gray, COLOR_BGR2GRAY); |
| |
| if (nightMode) |
| image = Scalar::all(0); |
| |
| if (needToInit) |
| { |
| |
| goodFeaturesToTrack(gray, points[1], MAX_COUNT, 0.01, (double)10, Mat(), 3,(bool) 0, 0.04); |
| cornerSubPix(gray, points[1], subPixWinSize, Size(-1, -1), termcrit); |
| addRemovePt = false; |
| } |
| else if (!points[0].empty()) |
| { |
| vector<uchar> status; |
| vector<float> err; |
| if (prevGray.empty()) |
| gray.copyTo(prevGray); |
| calcOpticalFlowPyrLK(prevGray, gray, points[0], points[1], status, err, winSize, |
| 3, termcrit, 0, 0.001); |
| size_t i, k; |
| for (i = k = 0; i < points[1].size(); i++) |
| { |
| if (addRemovePt) |
| { |
| if (norm(point - points[1][i]) <= 5) |
| { |
| addRemovePt = false; |
| continue; |
| } |
| } |
| |
| if (!status[i]) |
| continue; |
| |
| points[1][k++] = points[1][i]; |
| circle(image, points[1][i], 3, Scalar(0, 255, 0), -1, 8); |
| } |
| points[1].resize(k); |
| } |
| |
| if (addRemovePt && points[1].size() < (size_t)MAX_COUNT) |
| { |
| vector<Point2f> tmp; |
| tmp.push_back(point); |
| |
| |
| |
| |
| cornerSubPix(gray, tmp, winSize, Size(-1, -1), termcrit); |
| points[1].push_back(tmp[0]); |
| addRemovePt = false; |
| } |
| |
| needToInit = false; |
| imshow("LK Demo", image); |
| |
| char c = (char)waitKey(10); |
| if (c == 27) |
| break; |
| switch (c) |
| { |
| case 'r': |
| needToInit = true; |
| break; |
| case 'c': |
| points[0].clear(); |
| points[1].clear(); |
| break; |
| case 'n': |
| nightMode = !nightMode; |
| break; |
| } |
| |
| std::swap(points[1], points[0]); |
| cv::swap(prevGray, gray); |
| } |
| |
| return 0; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?