首页 > 基础资料 博客日记
【Java版本OpenCV】无敌OpenCV越学越爽Java版代码持续更新(环境搭建|核心代码)
2024-06-30 11:00:08基础资料围观213次
文章【Java版本OpenCV】无敌OpenCV越学越爽Java版代码持续更新(环境搭建|核心代码)分享给大家,欢迎收藏Java资料网,专注分享技术知识
特别说明
- 本文为B站李超老师的无敌Opencv越学越爽Java版代码(个人学习笔记),原视频为python语言讲解的,纯理论知识可直接看视频,实战代码为对应的Java版本,已经跟完B站所有章节,代码后续找时间补到章节名称下
- 个人感觉有些章节可以忽略的在章节下面做了备注,比如各种环境的安装,java可以直接用免安装的方式运行,所以这几节可以不看,节省点时间
- 个人感觉最用有的时区域找图,截图桌面图片,再桌面图片里寻找目标图片,拿到目标点的中心坐标,然后就可以利用Robot来实现各种鼠标键盘操作了,另外还有人脸识别,在桌面区域里面找人脸,就是不知道能不能识别出穿越火线里面的人脸,只要能识别到是不是可以用Robot控制鼠标移动到脑袋中间位置,在然后实现爆头▄︻┻┳═一…… ☆(>○<)效果,你们觉得那些功能比较实用,可以留言讨论
- B站教程链接https://www.bilibili.com/video/BV14P411D7MH/?spm_id_from=333.337.search-card.all.click&vd_source=ab54f52e92aff1f918ef3cbff7d66562
Java版Opencv从入门到入坑
1-2 OpenCV导学
1-3 计算机视觉到底是什么
以上两节看视频介绍,无代码
2-1 Mac下命令方式搭建OpenCV开发环境(加片头)
2-2 Windows下搭建OpenCV开发环境
2-3 Ubuntu下搭建OpenCV开发环境
2-4 Windows下源码方式编译OpenCV
2-5 Windows下C++使用OpenCV库
2-6 如何利用工具高效开发OpenCV
以上章节采免安装方式,所以安装章节可以直接跳过,节约点时间用springboot整合OpenCV(也可以用maven项目或者简单的java项目),主要是引入一个jar包和库文件,jar跨平台,库文件不跨平台,所以要区分windows和linux,至于工具idea就ok.
环境安装可以参考:springboot免安装整合Opencv兼容windows和linux
3-1 明晰课程项目
3-2 如何通过OpenCV创建显示窗口
3-3 如何通过OpenCV加载显示图片
3-4 两招解决OpenCV加载图片问题
实战代码
/**
* 读取图片并显示
*/
public class P1ReadAndDisplayImage {
public static void main(String[] args) {
// 加载Opencv库 不一定要在项目里面,需要绝对路径
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 读取图片
Mat img = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// 在hello窗口中显示图片
HighGui.imshow("hello", img);
// 等待按键 不设置设计会一直等待
HighGui.waitKey();
// 销毁所有窗口
HighGui.destroyAllWindows();
// 退出系统
System.exit(0);
}
}
3-5 如何通过OpenCV保存文件
public class P2SaveImage {
public static void main(String[] args) {
// 加载Opencv库 不一定要在项目里面,需要绝对路径
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 读取图片
Mat img = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// 保存图片 图片格式可以和原图片一致,也可以不一致
String fileName = "src/main/resources/tmp/lenna1.jpg";
Imgcodecs.imwrite(fileName, img);
}
}
3-6 如何利用OpenCV从摄像头采集视频
public class P3CameraStudy {
public static void main(String[] args) {
// 加载动态库
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 打开默认摄像头(索引为0)
VideoCapture capture = new VideoCapture(0);
// 检查摄像头是否成功打开
if (!capture.isOpened()) {
System.out.println("无法打开摄像头。");
return;
}
// 从摄像头读取并显示每一帧
Mat frame = new Mat();
while (capture.read(frame)) {
// 显示图片 HighGui用户界面相关
HighGui.imshow("Camera", frame);
// 等待3毫秒 也就是每3毫秒从摄像头读取一帧
int key = HighGui.waitKey(3);
// 如果输入q 则释放资源
if (key == 'q' || key == 'Q') {
// 销毁所有窗口
HighGui.destroyAllWindows();
// 释放 VideoCapture 对象
capture.release();
System.exit(0);
break;
}
}
// 销毁所有窗口
HighGui.destroyAllWindows();
// 释放 VideoCapture 对象
capture.release();
System.exit(0);
}
}
3-7 如何从多媒体文件中读取视频帧
3-8 如何将视频数据录制成多媒体文件
public class P4VideoStudy {
public static void main(String[] args) {
// 加载动态库
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 读取本地视频
VideoCapture capture = new VideoCapture("src/main/resources/video/video.mp4");
// 获取视频的宽度、高度和帧数
double width = capture.get(Videoio.CAP_PROP_FRAME_WIDTH);
double height = capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
double frameCount = capture.get(Videoio.CAP_PROP_FRAME_COUNT);
// 获取视频的帧数和总时长
double totalSeconds = frameCount / capture.get(Videoio.CAP_PROP_FPS);
// 计算平均帧率
double fps = frameCount / totalSeconds;
// 输出视频信息
System.out.println("视频宽度: " + width);
System.out.println("视频高度: " + height);
System.out.println("视频帧数: " + frameCount);
System.out.println("总时长: " + totalSeconds);
System.out.println("平均帧率: " + fps);
// 定义输出视频文件路径
String outputFilePath = "src/main/resources/tmp/output_video.mp4";
// 定义视频属性 width 和 height 不对写不进去
Size frameSize = new Size(width, height);
// 创建 VideoWriter 对象
VideoWriter videoWriter = new VideoWriter(outputFilePath, VideoWriter.fourcc('H', '2', '6', '4'), fps, frameSize, true);
// 检查视频是否成功打开
if (!capture.isOpened()) {
System.out.println("无法打开视频");
return;
}
// 检查 VideoWriter 对象是否成功初始化
if (!videoWriter.isOpened()) {
System.out.println("错误:无法打开视频文件以进行写入。");
return;
}
// 从视频读取并显示每一帧
Mat frame = new Mat();
while (capture.read(frame)) {
if (!frame.empty()) {
videoWriter.write(frame);
}
// 显示图片 HighGui用户界面相关
HighGui.imshow("Video", frame);
// 输入一次就中断了
int key = HighGui.waitKey(30);
System.out.println("key = " + key+"\t" + (char)key);
if (key == 'q' || key == 'Q') {
HighGui.destroyAllWindows();
capture.release();
videoWriter.release();
System.exit(0);
break;
}
}
HighGui.destroyAllWindows();
capture.release();
videoWriter.release();
System.exit(0);
}
}
3-9 代码优化
3-10 OpenCV控制鼠标
3-11 OpenCV中的TrackBar控件
3-12 实战TrackBar的使用
以上章节感觉没必要看,可直接忽略
4-1 RGB与BGR【OpenCV的色彩空间】
4-2 HSV与HSL【OpenCV的色彩空间】
4-3 实战OpenCV色彩空间转换
纯理论,可直接看视频
4-4 图像操作的基石Numpy【基础操作】
4-5 Numpy基本操作之矩阵的检索与赋值
4-6 Numpy基本操作三-ROI
以上三节直接忽略,Java提供了ROI的api(ROI 感兴趣的区域,就是一张图片中自己比较关心的那部分)
4-8 OpenCV的重要结构体Mat
4-9 Mat的深拷贝与浅拷贝
插播一个显示图片的工具类,解决图片显示在一起的位置,效果图片在屏幕上排列
public static void show(LinkedHashMap<String, Mat> mats) {
// 获取默认工具包
Toolkit toolkit = Toolkit.getDefaultToolkit();
// 获取屏幕的尺寸
Dimension screenSize = toolkit.getScreenSize();
// 输出屏幕宽度和高度
int i = 0;
int x = 0;
int y = 0;
int xSpacing = 10;
int ySpacing = 40;
for (Map.Entry<String, Mat> entry : mats.entrySet()) {
Mat mat = entry.getValue();
String winName = entry.getKey();
System.out.println("winName = " + winName);
HighGui.imshow(winName, mat);
if (i > 0) {
x += (mat.cols() + xSpacing);
if (x + mat.cols() > screenSize.width) {
x = 0;
y += (mat.rows() + ySpacing);
}
}
HighGui.moveWindow(winName, x, y);
i++;
}
HighGui.waitKey();
}
public class P490MatCopyStudy {
public static void main(String[] args) {
// 加载动态库
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 读取图片
Mat image = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// 是深拷贝
Mat clone = image.clone();
// 深拷贝
Mat copyTo = new Mat();
image.copyTo(copyTo);
// 在image上上绘制文本
// 文本的位置
Point textPosition = new Point(50, 50);
String text = "Hello, OpenCV!";
// 白色,字体大小为 1.0,线宽为 2
Imgproc.putText(image, text, textPosition, Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 255), 2);
LinkedHashMap<String, Mat> images = new LinkedHashMap<>();
images.put("原图", image);
images.put("clone", clone);
images.put("copyTo", copyTo);
OpenCVUtil.show(images);
HighGui.destroyAllWindows();
}
}
说明:通过以上代码可以看出,在Java中clone和copyTo均为深拷贝
4-11 图像的多种属性
4-12 通道的分割与合并
public class P412MatSplitAndMerge {
public static void main(String[] args) {
// 加载动态库
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 读取原图
Mat image = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// 显示图片
HighGui.imshow("原图", image);
// 分离通道
List<Mat> channels = new ArrayList<>();
Core.split(image, channels);
for (int i = 0; i < channels.size(); i++) {
Mat mat = channels.get(i);
// 分离出来的3个通道均为单通道,故显示出来都是黑白图片
HighGui.imshow("通道" + i, mat);
}
List<Mat> mergeChannels = new ArrayList<>();
mergeChannels.add(channels.get(0));
mergeChannels.add(channels.get(1));
mergeChannels.add(channels.get(2));
Mat newMat = new Mat();
// 合并通道
Core.merge(mergeChannels,newMat);
HighGui.imshow("合并后的图像", newMat);
HighGui.waitKey();
HighGui.destroyAllWindows();
System.exit(0);
}
}
绘制基本图形
5-1 OpenCV绘制直线
5-2 OpenCV椭圆的绘制
5-3 OpenCV椭圆的绘制
5-4 OpenCV绘制多边形
5-5 OpenCV绘制文本5-6 OpenCV大作业-实现鼠标绘制基本图形
5-7 OpenCV基本图形绘制小结
代码实战
public class P500BasicShapeDrawingExample {
public static void main(String[] args) {
// 加载动态库
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 创建一个黑色背景的图像
Mat image = new Mat(400, 600, CvType.CV_8UC3, new Scalar(0, 0, 0)); // 400x600 大小,3 通道的黑色图像
// 在图像上绘制基本图形
Point center = new Point(300, 200); // 圆心坐标
Scalar color = new Scalar(0, 255, 0); // 颜色 (BGR 格式)
// 绘制圆
Imgproc.circle(image, center, 100, color, 2); // 中心为 (300, 200),半径为 100,边界宽度为 2,绿色
// 绘制矩形
Point topLeft = new Point(100, 100); // 左上角坐标
Point bottomRight = new Point(500, 300); // 右下角坐标
Imgproc.rectangle(image, topLeft, bottomRight, new Scalar(0, 0, 255), 3); // 左上角 (100, 100),右下角 (500, 300),红色,边界宽度为 3
// 绘制直线
Point start = new Point(50, 50); // 起始点坐标
Point end = new Point(550, 350); // 结束点坐标
Imgproc.line(image, start, end, new Scalar(255, 0, 0), 1); // 蓝色,线宽为 1
// 在图像上绘制文本
Point textPosition = new Point(50, 50); // 文本的位置
String text = "Hello, OpenCV!"; // 要绘制的文本
Imgproc.putText(image, text, textPosition, Imgproc.FONT_HERSHEY_SIMPLEX, 1.0, new Scalar(255, 255, 255), 2); // 白色,字体大小为 1.0,线宽为 2
HighGui.imshow("基本图形的绘制", image);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
}
效果
6-1 图像的加法运算
6-2 图像的减法运算
public class P620ImageArithmeticExample {
public static void main(String[] args) {
// // 加载动态库
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 加载两个图像
String imagePath1 = "src/main/resources/img/lenna1.png";
Mat image1 = Imgcodecs.imread(imagePath1);
// 检查图像是否成功加载
if (image1.empty()) {
System.out.println("Error: Couldn't load images.");
return;
}
HighGui.imshow("原图", image1);
// 创建与图像1尺寸相同的图像2,每个像素值为100
Mat image2 = new Mat(image1.size(), image1.type(), new Scalar(100));
// 创建一个与图像1尺寸和类型相同的空白图像,用于存储结果
Mat result4add = new Mat(image1.size(), image1.type());
Mat result4subtract = new Mat(image1.size(), image1.type());
// 加法运算
Core.add(image1, image2, result4add);
HighGui.imshow("图像相加", result4add);
// 减法运算
Core.subtract(image1, image2, result4subtract);
HighGui.imshow("图像相减", result4subtract);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
}
图像的明暗变化(图像加减乘除混合运算)
public class P621DarknessAdjustmentExample {
public static void main(String[] args) {
// 加载动态库
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 加载两个图像
Mat image1 = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// 检查图像是否成功加载
if (image1.empty()) {
System.out.println("Error: Couldn't load images.");
return;
}
HighGui.imshow("原图像", image1);
// 定义暗度调整系数(在 0 到 1 之间)
double darknessFactor = 0.5; // 减少 50%
// 将图像1的每个像素值乘以暗度调整系数
// rtype:转换后的目标数据类型。如果值为 -1,则表示使用与源 Mat 对象相同的数据类型。
// 原像素值*alpha+beta
Mat clone = image1.clone();
clone.convertTo(clone, -1, darknessFactor, 0);
HighGui.imshow("明暗变化后", clone);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
}
6-3 图像的溶合
public class P630ImageFusionExample {
public static void main(String[] args) {
// 加载动态库
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 读取图像1和图像2
Mat image1 = Imgcodecs.imread("src/main/resources/img/dog.jpg");
Mat image2 = Imgcodecs.imread("src/main/resources/img/background.jpg");
// 融合要求两张图片具有相同尺寸
Size size = getSize(image1, image2);
// 图像融合
Mat blendedImage = blendImages(resizeImages(image1, size), resizeImages(image2, size));
// 显示融合后的图像
HighGui.imshow("Blended Image", blendedImage);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
private static Size getSize(Mat image1, Mat image2) {
int minWidth = Math.min(image1.width(), image2.width());
int minHeight = Math.min(image1.height(), image2.height());
return new Size(minWidth, minHeight);
}
// 将图像调整为size大小
private static Mat resizeImages(Mat image, Size size) {
Mat mat = new Mat(size, image.type());
Imgproc.resize(image, mat, size);
return mat;
}
// 图像融合
private static Mat blendImages(Mat image1, Mat image2) {
double alpha = 0.9; // 调整融合的权重
Mat blendedImage = new Mat();
Core.addWeighted(image1, alpha, image2, 1 - alpha, 0, blendedImage);
return blendedImage;
}
}
原图1
原图2
融合效果
6-4 OpenCV位运算-非操作
public class P640ImageNegationExample {
public static void main(String[] args) {
// 加载动态库
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 读取图像
Mat image = Imgcodecs.imread("src/main/resources/img/lenna1.png");
HighGui.imshow("原图", image);
Mat mat = new Mat();
Core.bitwise_not(image, mat);
// 显示融合后的图像
HighGui.imshow("图像的非运算", mat);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
}
6-5 OpenCV位操作-与运算
6-6 OpenCV位操作-或与异或
6-7 大作业-为图像添加水印
public class P670AddLogo {
public static void main(String[] args) {
// 加载动态库
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 1. 引入图片
Mat background = Imgcodecs.imread("src/main/resources/img/background.jpg");
// 2. 制作logo
Mat logo = new Mat(200, 200, CvType.CV_8UC3, new Scalar(0, 0, 0));
Mat mask = new Mat(200, 200, CvType.CV_8UC1, new Scalar(0, 0, 0));
Point topLeft = new Point(20, 20);
Point bottomRight = new Point(120, 120);
Imgproc.rectangle(logo, topLeft, bottomRight, new Scalar(0, 0, 255), 2);
Imgproc.rectangle(mask, topLeft, bottomRight, new Scalar(255, 255, 255), 2);
topLeft = new Point(80, 80);
bottomRight = new Point(180, 180);
Imgproc.rectangle(logo, topLeft, bottomRight, new Scalar(0, 255, 0), 2);
Imgproc.rectangle(mask, topLeft, bottomRight, new Scalar(255, 255, 255), 2);
Mat m = new Mat();
Core.bitwise_not(mask, m);
HighGui.imshow("logo", logo);
HighGui.imshow("mask", mask);
HighGui.imshow("m", m);
// 3. 计算添加位置,将添加位置变黑
Mat roi = new Mat(background, new Rect(0, 0, 200, 200));
HighGui.imshow("roi", roi);
Mat tmp = new Mat();
Core.bitwise_and(roi, roi, tmp, m);
HighGui.imshow("tmp", tmp);
Mat dst = new Mat();
Core.add(tmp, logo, dst);
HighGui.imshow("dst", dst);
// 4.利用add,将图片和logo叠加到一起
Mat submat = background.submat(new Rect(0, 0, 200, 200));
dst.copyTo(submat);
HighGui.imshow("background", background);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
}
7-1 图像的放大与缩小
public class P710Scale {
public static void main(String[] args) {
// 加载动态库
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 读取图像
Mat originalImage = Imgcodecs.imread("src/main/resources/img/idea.png");
// 定义缩放后的图像大小
Size newSize = new Size(originalImage.width() * 5, originalImage.height() * 5);
// 缩放图像(使用双立方插值)
Mat resizedImage = new Mat();
Imgproc.resize(originalImage, resizedImage, newSize, 0, 0, Imgproc.INTER_AREA);
// 显示原始图像和缩放后的图像
HighGui.imshow("Original Image", originalImage);
HighGui.imshow("Resized Image", resizedImage);
HighGui.waitKey(0);
HighGui.destroyAllWindows();
System.exit(0);
}
}
说明:第一张是原图,第二张是放大5倍的图,放大之后图像会模糊
7-2 图像的翻转
7-3 图像的旋转
/**
* 图像的反转
* 0:沿X轴翻转(垂直翻转)
* 1:沿Y轴翻转(水平翻转)
* -1:同时沿X轴和Y轴翻转
*/
public class P730ImageFlipExample {
public static void main(String[] args) {
// 加载动态库
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 读取图像
Mat originalImage = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// 沿X轴翻转(垂直翻转)
Mat dstX = new Mat();
Core.flip(originalImage, dstX, 0);
// 沿Y轴翻转(水平翻转)
Mat dstY = new Mat();
Core.flip(originalImage, dstY, 1);
Mat dstXY = new Mat();
Core.flip(originalImage, dstXY, -1);
LinkedHashMap<String, Mat> images = new LinkedHashMap<>();
images.put("原图", originalImage);
images.put("沿着X轴翻转", dstX);
images.put("沿着Y轴翻转", dstY);
images.put("同时沿着XY轴翻转", dstXY);
OpenCVUtil.show(images);
HighGui.destroyAllWindows();
System.exit(0);
}
}
效果图
7-4 仿射变换之图像平移
7-5 仿射变换之获取变换矩阵
7-6 仿射变换之变换矩阵之二
/**
* 仿射变幻
*/
public class P760ImageRotateExample {
public static void main(String[] args) {
// 加载动态库
System.load(new File("src/main/resources/lib/opencv/opencv_java490.dll").getAbsolutePath());
// 读取图像
Mat originalImage = Imgcodecs.imread("src/main/resources/img/lenna1.png");
// 定义旋转角度(逆时针)
double angle = 45.0;
// 获取图像中心点
Point center = new Point(originalImage.cols() / 2, originalImage.rows() / 2);
// 计算旋转矩阵
Mat rotationMatrix = Imgproc.getRotationMatrix2D(center, angle, 1.0);
// 执行旋转变换
Mat rotatedImage = new Mat();
Imgproc.warpAffine(originalImage, rotatedImage, rotationMatrix, new Size(originalImage.cols(), originalImage.rows()));
// 显示原始图像和旋转后的图像
LinkedHashMap<String, Mat> images = new LinkedHashMap<>();
images.put("原图", originalImage);
images.put("逆时针旋转45°", rotatedImage);
OpenCVUtil.show(images);
HighGui.destroyAllWindows();
System.exit(0);
}
}
7-7 OpenCV透视变换
8-1 图像滤波
OpenCV提供了许多不同类型的滤波器,可以用于图像处理的各种任务。以下是一些常用的滤波器类型:
-
低通滤波:去噪
- 均值滤波器(Mean Filter):用于平滑图像并减少噪声。它计算像素周围区域的平均值,并用该平均值替换中心像素的值。
- 高斯滤波器(Gaussian Filter):也用于平滑图像并减少噪声,但相比均值滤波器,它更加平滑。它计算像素周围区域的加权平均值,权重由高斯函数确定。
- 中值滤波器(Median Filter):用于去除椒盐噪声等斑点噪声。它将像素周围区域的值排序,并用中值替换中心像素的值。
- 双边滤波器(Bilateral Filter):用于平滑图像并保持边缘清晰。它考虑了像素之间的空间距离和像素值之间的相似性,以确定滤波器的权重。
-
高通滤波:检测边缘
- Sobel(索贝尔)滤波器:用于边缘检测。它使用两个3x3的卷积核,分别计算图像的水平和垂直方向的梯度。
- Laplacian(拉普拉斯)滤波器:也用于边缘检测。它计算图像的二阶导数,并可以提取出图像中的边缘。
8-2 卷积相关概念
8-3 实战图像卷积
8-4 方盒滤波与均值滤波
8-5 高斯滤波
8-6 中值滤波
8-7 双边滤波
8-8 高通滤波-索贝尔算子
8-9 高通滤波-沙尔算子
8-10 高通滤波-拉普拉斯算子
8-11 边缘检测Canny
9-1 形态学概述
9-2 图像全局二值化
9-3 阈值类型
9-4 自适应阈值二值化
9-5 OpenCV腐蚀
9-6 获取形态学卷积核
9-7 OpenCV膨胀
9-8 开运算
9-9 闭运算
9-10 形态学梯度
9-11 顶帽运算
9-12 黑帽操作
10-1 什么是图像轮廓
10-2 查找轮廓
10-3 绘制轮廓
10-4 轮廓的面积与周长
10-5 多边形逼近与凸包
10-6 外接矩形
10-7 项目总览【车辆统计】
10-8 视频加载【车辆统计】
10-9 形态学处理【车辆统计】
10-10 去背景【车辆统计】
10-11 逻辑处理【车辆统计】
10-12 显示信息【车辆统计】
11-1 特征检测的基本概念
11-2 Harris角点检测
11-3 Shi-Tomasi角点检测
11-4 SIFT关键点检测
11-5 SIFT计算描述子
11-6 SURF特征检测
11-7 OBR特征检测
11-8 暴力特征匹配
11-9 FLANN特征匹配
11-10 实战flann特征匹配
11-11 图像查找
11-12 大作业-图像拼接基础知识
11-13 大作业-图像拼接(一)
文章来源:https://blog.csdn.net/weixin_41883161/article/details/136614485
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: