Opencv学习-图像变换

news2024/9/28 15:28:51

1. 图像连接

        图像连接是指将两个具有相同高度或者宽度的图像连接在一起,图像的下(左)边缘是另一个图像的上(右)边缘。图像连接常在需要对两幅图像内容进行对比或者内容中存在对应信息时显示 对应关系时使用。例如,在使用线段连接两幅图像中相同的像素点时,就需要首先将两幅图像组成 一幅新的图像,再连接相同的区域。
        OpenCV 4 中针对图像左右连接和上下连接两种方式提供了两个不同的函数, vconcat() 函数用于实现图像或者矩阵数据的上下连接,该函数可以连接存放在数组变量中的多个 Mat 类型的数据, 也可以直接连接两个Mat 类型的数据。

1.1 vconcat函数介绍(竖向连接)

void cv::vconcat(const Mat * src, size_t nsrc, OutputArray dst )

src:Mat矩阵类型的数组。
nsrc:数组中 Mat 类型数据的个数。
dst:连接后的 Mat类矩阵。

        该函数对存放在数组矩阵中的Mat 类型数据进行纵向连接。第一个参数是存放多个 Mat 类型数据的数组,要求数组中所有的 Mat 类型具有相同的列数并且具有相同的数据类型和通道数。第二个参数是数组中含有的 Mat 类型数据的个数。最后一个参数是拼接后输出的结果,结果的宽度与第一个 Mat 类型数据相同,高度为数组中所有 Mat 类型数据高度的总和,并且与第一个 Mat 类型数据具有相同的数据类型和通道数

void cv::vconcat(InputArray src1, InputArray src2, OutputArray dst )

src1:第一个需要连接的 Mat 类矩阵。
src2:第二个需要连接的 Mat 类矩阵,与第一个参数具有相同的宽度、数据类型和通道数。
dst:连接后的 Mat 类矩阵 

        该函数直接对两个 Mat 类型的数据进行竖向连接。前两个参数分别是需要连接的两个 Mat 类型变量,两者需要具有相同的宽度、数据类型及通道数,第三个参数是连接后的输出结果,在拼接结果中第一个参数在上方,第二个参数在下方。

        hconcat()函数用于实现图像或者矩阵数据的左右连接。与 vconcat() 函数类似,该函数既可以连接存放在数组变量中的多个 Mat 类型的数据,又可以直接连接两个 Mat 类型的数据。

1.2 hconcat函数原型

void cv::hconcat(const Mat * src, size_t nsrc, OutputArray dst )
void cv::hconcat(InputArray src1, InputArray src2, OutputArray dst )

1.3  示例代码

#include <opencv2/opencv.hpp> 
#include <iostream> 
 
using namespace std; 
using namespace cv; 
 
int main() 
{ 
    //矩阵数组的横竖连接
    Mat matArray[] = { Mat(1, 2, CV_32FC1, cv::Scalar(1)), 
    Mat(1, 2, CV_32FC1, cv::Scalar(2)) }; 
    Mat vout, hout; 
    cout << "matArray[0]  ==   " << matArray[0] << "matArray[1]  ==   " << matArray[1] << endl;
    vconcat(matArray, 2, vout); 
    cout << "图像数组竖向连接:" << endl << vout << endl; 
    hconcat(matArray, 2, hout); 
    cout << "图像数组横向连接:" << endl << hout << endl; 
    
    //矩阵的横竖拼接
    Mat A = (cv::Mat_<float>(2, 2) << 1, 7, 2, 8); 
    Mat B = (cv::Mat_<float>(2, 2) << 4, 10, 5, 11); 
 
    cout << "A : \n"<< A << "\nB : \n"<< B << endl;
    Mat vC, hC; 
    vconcat(A, B, vC); 
    cout << "多个图像竖向连接:" << endl << vC << endl; 
    hconcat(A, B, hC); 
    cout << "多个图像横向连接:" << endl << hC << endl; 
    
    //读取 4 个子图像,00 表示左上角、01 表示右上角、10 表示左下角、11 表示右下角
    Mat img00 = imread("lena00.png"); 
    Mat img01 = imread("lena01.png"); 
    Mat img10 = imread("lena10.png"); 
    Mat img11 = imread("lena11.png"); 
    if (img00.empty()||img01.empty()||img10.empty()||img11.empty()) 
    { 
        cout << "请确认图像文件名称是否正确" << endl; 
        return -1; 
    } 
    //显示 4 个子图像
    imshow("img00", img00); 
    imshow("img01", img01); 
    imshow("img10", img10); 
    imshow("img11", img11); 
    
    //图像连接
    Mat img, img0, img1; 
    //图像横向连接
    hconcat(img00, img01, img0); 
    hconcat(img10, img11, img1); 
    //横向连接结果再进行竖向连接
    vconcat(img0, img1, img); 
    
    //显示连接图像的结果
    imshow("img0", img0); 
    imshow("img1", img1); 
    imshow("img", img); 
    waitKey(0); 
    return 0; 
}

1.4 结果 

2. 图像尺寸变换

        图像的尺寸变换实际上就是改变图像的长和宽,实现图像的缩放。在 OpenCV 4 中提供了 resize() 函数用于将图像修改成指定尺寸。

2.1 resize函数介绍

void cv::resize(InputArray src, OutputArray dst, Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR )

src:输入图像。
dst:输出图像,图像的数据类型与 src 相同。
dsize:输出图像的尺寸。
fx:水平轴的比例因子,如果将水平轴变为原来的两倍,则赋值为 2。
fy:垂直轴的比例因子,如果将垂直轴变为原来的两倍,则赋值为 2。
interpolation:插值方法的标志

        该函数主要用来对图像尺寸进行缩放,前两个参数分别是输入图像和尺寸缩放之后的输出图像。该函数的 dsize 和 fx ( fy )同时可以调整输出图像的参数,因此两类参数在实际使用时只需要使用一类,当根据两个参数计算出来的输出图像尺寸不一致时,以 dsize 设置的图像尺寸为准。这两类调整图像尺寸的参数的关系如下:

        最后一个参数是选择图像插值方法的标志。在图像缩放相同的尺寸时,选择不同的插值方法会具有不同效果 。一般来讲,如果要缩小图像,那么通常使用 INTER_AREA 标志会有较好的效果。而在放大图像时,采用 INTER_CUBIC 和 INTER_LINEAR 标志通常会有比较好的效果,这两个标志,前者计算速度较慢,后者速度较快,虽然前者效果较好,但是后者效果也相对比较理想。

        示例程序中首先以灰度图像的形式读入一幅图像,之后利用 INTER_AREA 将图像缩小,并分别利用INTER_CUBIC、INTER_NEAREST 和 INTER_LINEAR 这 3 种方法将图像放大到相同的尺寸,根据结果比较两种插值方法效果的差异。 

2.2 示例代码

#include <opencv2/opencv.hpp> 
#include <iostream> 
 
using namespace std; 
using namespace cv; 
 
int main() 
{ 
    Mat gray = imread("../pic/gril.jpg", IMREAD_GRAYSCALE); 
    if (gray.empty()) 
    { 
        cout << "请确认图像文件名称是否正确" << endl; 
        return -1; 
    } 
    cout << " width == " << gray.cols << "   height == " << gray.rows << endl;
    Mat smallImg, bigImg0, bigImg1, bigImg2; 
    resize(gray, smallImg, Size(300, 300), 0, 0, INTER_AREA); //先将图像缩小
    resize(smallImg, bigImg0, Size(300, 300), 0, 0, INTER_NEAREST); //最近邻插值
    resize(smallImg, bigImg1, Size(300, 300), 0, 0, INTER_LINEAR); //双线性插值
    resize(smallImg, bigImg2, Size(300, 300), 0, 0, INTER_CUBIC); //双三次插值
    //namedWindow("smallImg", WINDOW_NORMAL); //图像尺寸太小,一定要设置可以调节窗口大小标志
    imshow("gray", gray); 
    imshow("smallImg", smallImg); 
    //namedWindow("bigImg0", WINDOW_NORMAL); 
    imshow("bigImg0", bigImg0);
    //namedWindow("bigImg1", WINDOW_NORMAL); 
    imshow("bigImg1", bigImg1); 
    //namedWindow("bigImg2", WINDOW_NORMAL); 
    imshow("bigImg2", bigImg2); 
    waitKey(0); 
    return 0; 
}

2.3 结果:

只需要弄前3个参数就好,一般只需要做裁剪就好了 

3. 图像翻转

3.1 flip函数介绍(翻转)

void cv::flip(InputArray src, OutputArray dst, int flipCode )

src:输入图像。
dst:输出图像,与 src 具有相同的大小、数据类型及通道数。
flipCode:翻转方式标志。数值大于 0 表示绕 y 轴进行翻转;数值等于 0,表示绕 x 轴进行翻转;数值小于 0,表示绕两个轴翻转。

3.2 代码示例:

#include <opencv2/opencv.hpp> 
#include <iostream> 

using namespace std; 
using namespace cv; 

int main() 
{ 
    Mat img = imread("../pic/gril_1.jpg"); 
    if (img.empty()) 
    { 
        cout << "请确认图像文件名称是否正确" << endl; 
        return -1; 
    } 
    
    Mat img_x, img_y, img_xy; 
    flip(img, img_x, 0); //以 x 轴对称
    flip(img, img_y, 1); //以 y 轴对称
    flip(img, img_xy, -1); //先以 x 轴对称,再以 y 轴对称
    imshow("img", img); 
    imshow("img_x", img_x); 
    imshow("img_y", img_y); 
    imshow("img_xy", img_xy); 
    waitKey(0); 
    return 0; 
}

3.3 结果:

4. 图像仿射变换

        在 OpenCV 4 中并没有专门用于图像旋转的函数,而是通过图像的仿射变换实现图像的旋转。实现图像的旋转,首先需要确定旋转角度和旋转中心,之后确定旋转矩阵,最终通过仿射变换实现图像旋转。针对这个流程,OpenCV 4 提供了 getRotationMatrix2D() 函数用于计算旋转矩阵,提供了 warpAffine() 函数用于实现图像的仿射变换。下面首先介绍用于计算旋转矩阵的 getRotationMatrix2D() 函数,

4.1 getRotationMatrix2D()函数介绍

Mat cv::getRotationMatrix2D (Point2f center, double angle, double scale )

center:图像旋转的中心位置。
angle:图像旋转的角度,单位为度,正值为逆时针旋转。
scale:两个轴的比例因子,可以实现旋转过程中的图像缩放,不缩放则输入1。

        该函数输入旋转角度和旋转中心,返回图像旋转矩阵,返回值的数据类型为 Mat 类,是一个2× 3 的矩阵。如果我们已知图像旋转矩阵,那么可以自己生成旋转矩阵而不调用该函数。该函数生成的旋转矩阵与旋转角度和旋转中心的关系如下:

4.2  warpAffine()函数介绍

void cv::warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, 
int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scalar& 
borderValue = Scalar() )

src:输入图像。
dst:仿射变换后输出图像,与src数据类型相同,尺寸与dsize相同。
M:  2×3的变换矩阵。
dsize:输出图像的尺寸。
flags:插值方法标志,。
borderMode:像素边界外推方法标志。
borderValue:填充边界使用的数值,默认情况下为0。

                                                                 插值方法标志

                                                            边界外推的方法标志

        这个函数使用仿射变换来将输入图像映射到输出图像。仿射变换包括旋转、缩放、平移等操作,但不包括扭曲和剪切。这个函数非常有用,特别是在需要将图像映射到另一个大小或以特定方式旋转或倾斜图像时。 

        仿射变换又称为三点变换。如果知道变换前后两幅图像中 3 个像素点坐标的对应关系,就可以 求得仿射变换中的变换矩阵 MOpenCV 4 提供了利用 3 个对应像素点来确定变换矩阵 M 的函数 getAffineTransform(),

warpAffine函数可以参考:

【C++】【Opencv】cv::warpAffine()仿射变换函数详解,实现平移、缩放和旋转等功能-CSDN博客

4.3 getAffineTransform函数介绍

Mat cv::getAffineTransform(const Point2f src[], const Point2f dst[] )

src[]:源图像中的 3 个像素坐标。

dst[] :目标图像中的 3 个像素坐标
该函数两个输入量都是存放浮点坐标的数组,在生成数组的时候,与像素点的输入顺序无关, 但是需要保证像素点的对应关系,函数的返回值是一个 2 × 3 的变换矩阵。有了前面变换矩阵的取,就可以利用 warpAffine() 函数实现矩阵的仿射变换。

4.4 代码示例:

#include <opencv2/opencv.hpp> 
#include <iostream> 
#include <vector> 

using namespace std; 
using namespace cv; 

int main() 
{ 
    Mat img = imread("../pic/gril_1.jpg"); 
    if (img.empty()) 
    { 
        cout << "请确认图像文件名称是否正确" << endl; 
        return -1; 
    } 
    
    Mat rotation0, rotation1, img_warp0, img_warp1,img_warp2; 
    double angle = -90; //设置图像旋转的角度
    Size dst_size(img.rows, img.cols); //设置输出图像的尺寸
    Point2f center(img.rows / 2.0, img.cols / 2.0); //设置图像的旋转中心
    rotation0 = getRotationMatrix2D(center, angle, 1); //计算仿射变换矩阵

    //cout << "rotation0 : \n" <<  rotation0 << endl;
    warpAffine(img, img_warp0, rotation0, dst_size); //进行仿射变换
    imshow("img_warp0", img_warp0); 
    //根据定义的 3 个点进行仿射变换
    Point2f src_points[3]; 
    Point2f dst_points[3]; 
    src_points[0] = Point2f(0, 0); //原始图像中的 3 个点
    src_points[1] = Point2f(0, (float)(img.cols - 1)); 
    src_points[2] = Point2f((float)(img.rows - 1), (float)(img.cols - 1)); 
    //仿射变换后图像中的 3 个点
    dst_points[0] = Point2f((float)(img.rows)*0.1, (float)(img.cols)*0.10); 
    dst_points[1] = Point2f((float)(img.rows)*0.1, (float)(img.cols)*0.80); 
    dst_points[2] = Point2f((float)(img.rows)*0.81, (float)(img.cols)*0.8); 
    rotation1 = getAffineTransform(src_points, dst_points); //根据对应点求取仿射变换矩阵
    //cout << "rotation1 : \n" <<  rotation1 << endl;
    warpAffine(img, img_warp1, rotation1, dst_size); //进行仿射变换
    warpAffine(img, img_warp2, rotation1, dst_size,WARP_FILL_OUTLIERS,BORDER_REPLICATE,10); //进行仿射变换
    imshow("img_warp1", img_warp1); 
    imshow("img_warp2", img_warp2); 
    waitKey(0); 
    return 0; 
}

 4.5 结果:

5. 图像透视变换

        透视变换是按照物体成像投影规律进行变换,即将物体重新投影到新的成像平面,示意图如下图所示。透视变换常用于机器人视觉导航研究中,由于相机视场与地面存在倾斜角使得物体成像产生畸变,通常通过透视变换实现对物体图像的校正。在透视变换中,透视前的图像和透视后的图像之间的变换关系可以用一个 3×3 的变换矩阵表示,该矩阵可以通过两幅图像中 4 个对应点的坐标求取,因此透视变换又称作“四点变换”。与仿射变换一样,OpenCV 4 中提供了根据 4 个对应点求取变换矩阵的 getPerspectiveTransform()函数和进行透视变换的 warpPerspective()函数。

透视变换原理示意图 

5.1 getPerspectiveTransform()函数原型

Mat cv::getPerspectiveTransform (const Point2f src[], const Point2f dst[], int solveMethod = DECOMP_LU )

src[]:原图像中的 4 个像素坐标。
dst[]:目标图像中的 4 个像素坐标。
solveMethod:选择计算透视变换矩阵方法的标志

        该函数两个输入量都是存放浮点坐标的数组,在生成数组的时候,与像素点的输入顺序无关, 但是需要注意像素点的对应关系。该函数的返回值是一个 3 × 3 的变换矩阵。该函数中最后一个参 数是根据 4 个对应点坐标计算透视变换矩阵方法的选择标志。
getPerspectiveTransform() 函数计算方法标志

5.2 warpPerspective()函数原型

void cv::warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT,const Scalar & borderValue = Scalar() )

src:输入图像。
dst:透视变换后输出图像,与 src 数据类型相同,但是尺寸与 dsize 相同。
M:3×3 的变换矩阵。
dsize:输出图像的尺寸。
flags:插值方法标志。
borderMode:像素边界外推方法的标志。
borderValue:填充边界使用的数值,默认情况下为 0。

        该函数所有参数的含义与 warpAffine()函数的参数含义相同,这里不再赘述 。示例代码中平面图片经过透视变换有立体感觉。

5.3 示例代码

#include <opencv2/opencv.hpp> 
#include <iostream> 

using namespace cv; 
using namespace std; 

int main() 
{ 
    Mat img = imread("../pic/gril.jpg"); 
    if (img.empty()) 
    { 
        cout << "请确认图像文件名称是否正确" << endl; 
        return -1; 
    } 
    
    Point2f src_points[4]; 
    Point2f dst_points[4]; 
    //通过 Image Watch 查看的二维码 4 个角点坐标
    src_points[0] = Point2f(0, 0); 
    src_points[1] = Point2f(647, 0); 
    src_points[2] = Point2f(0, 324); 
    src_points[3] = Point2f(647, 324); 
    //期望透视变换后二维码 4 个角点的坐标
    dst_points[0] = Point2f(100.0, 150.0); 
    dst_points[1] = Point2f(527.0, 150.0); 
    dst_points[2] = Point2f(0.0, 300); 
    dst_points[3] = Point2f(627.0, 300); 
    Mat rotation, img_warp; 
    rotation = getPerspectiveTransform(src_points, dst_points); //计算透视变换矩阵
    warpPerspective(img, img_warp, rotation, img.size()); //透视变换投影
    imshow("img", img); 
    imshow("img_warp", img_warp); 
    waitKey(0);
    return 0;
}

5.4 结果

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1980722.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全国十大起名大师排行榜,中国最厉害三个起名大师是谁?

全国十大起名大师排行榜&#xff0c;中国最厉害三个起名大师是谁&#xff1f; 山东济南最受欢迎的起名大师有多位&#xff0c;其中较为知名的包括&#xff1a; ‌颜廷利&#xff0c;被誉为山东济南最出名的起名大师之一&#xff0c;还是现代山东文化名人&#xff0c;通过魔方解…

人工智能时代下,国产服务器操作系统如何加快发展?

人工智能时代下&#xff0c;国产服务器操作系统如何加快发展&#xff1f; 云智融合浪潮下&#xff0c;服务器操作系统产业未来发展将走向何方&#xff1f;英特尔和龙蜥的合作&#xff0c;能为国产操作系统的发展带来什么&#xff1f;双方如何通过合作布局“云AI”时代的未来&am…

配有知识库的AI助手与大模型问答相比,各有哪些优缺点?

1. 配有知识库支持的AI助手 优点&#xff1a; 精确性&#xff1a;知识库是由专业人员整理和维护的&#xff0c;其中的信息通常是经过验证和准确的。因此&#xff0c;配有知识库的AI助手可以提供准确的答案&#xff0c;并且在特定领域的问题上表现良好。可控性&#xff1a;知识…

合并重叠的区间

这一题不能用差分数组&#xff0c;因为 [1 , 4] [5, 6] 这个就会被合并&#xff0c;正确的做法就是先排序 bool cmp(vector<int> a, vector<int> b) {if (a[0] < b[0]) return 1;if (a[0] b[0]) return a[1] < b[1];return 0; } class Solution { public:ve…

Python酷库之旅-第三方库Pandas(065)

目录 一、用法精讲 256、pandas.Series.sparse方法 256-1、语法 256-2、参数 256-3、功能 256-4、返回值 256-5、说明 256-6、用法 256-6-1、数据准备 256-6-2、代码示例 256-6-3、结果输出 257、pandas.DataFrame.sparse方法 257-1、语法 257-2、参数 257-3、功…

分享一个基于人脸识别的小区物业管理系统Spring Boot(源码、调试、LW、开题、PPT)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人 八年开发经验&#xff0c;擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等&#xff0c;大家有这一块的问题可以一起交流&…

我花了一天时间,搭了个专属知识库,部署上线了,手把手教,不信你学不会

自动开了这个号以后&#xff0c;陆陆续续写了很多干货文章&#xff0c;一方面是可以帮助自己梳理思路&#xff0c;另一方面也方便日后查找相关内容。 但是&#xff0c;我想检索某个关键词是在之前哪篇文章写过的&#xff0c;就有点捉急了。CSDN 还好&#xff0c;可以检索到相关…

Python 算法交易实验77 QTV200日常推进-经典策略

说明 最初(去年7月)快快上了一版&#xff0c;到现在差不多正好一年。总体上当时做的还是蛮粗糙的&#xff0c;没有考虑模式&#xff0c;只是简单的用判别模型做了一道。 过去的一年&#xff0c;显然不是特别好的一年。我知道的大部分还是以亏损居多。这版策略竟然没有亏钱&am…

【C++11】:lambda表达式function包装器

目录 前言一&#xff0c;可变参数模板1.1 简单认识1.2 STL容器中的empalce系列相关接口 二&#xff0c;lambda表达式2.1 lambda表达式语法2.2 探索lambda底层 三&#xff0c;包装器3.1 function包装器3.2 bind 四&#xff0c;类的新功能4.1 默认成员函数4.2 关键字default4.3 关…

c++数据保存到.csv文件中,并用opencv离线仿真显示

测试可能不是很方便&#xff0c;希望采集一次数据后期还可以使用&#xff0c;这里提供一个案例&#xff1a; 数据写入fosepose.csv //write.cpp #include <iostream> #include <fstream> #include <iomanip> #include <cstdint> #include <chrono…

达梦数据库的系统视图v$sql_plan

达梦数据库的系统视图v$sql_plan 达梦数据库的V$SQL_PLAN视图主要用于显示缓存中的SQL执行计划信息&#xff0c;在 ini 参数 USE_PLN_POOL !0 时才统计。通过查询这个视图&#xff0c;用户可以获取到缓存中的SQL语句的执行计划&#xff0c;这对于监控和分析数据库中的SQL执行情…

excel去掉小数点前的内容

可以使用"通配符"法 1、去除小数点后的内容 我们按CTRLH&#xff0c;调出查找替换功能 然后在查找内容里面&#xff0c;输入.* 星号是通配符&#xff0c;一点加通配符&#xff0c;表示将小数点后面的任意字符给去掉 2、去除小数点前的内容 我们按CTRLH&#xff0c;调…

Python处理和生成 Word 文档库之python-docx使用详解

概要 在日常工作中,处理和生成 Word 文档是一个常见的需求。Python 提供了一个强大的库 python-docx,使得操作 Word 文档变得简单和高效。python-docx 可以帮助我们创建、修改和读取 Word 文档,适用于各种应用场景,如自动化报告生成、批量文档处理等。本文将详细介绍 pyth…

Spring AOP:面向切面编程的最佳实践 ( 一 )

1.AOP思想 1.1.为什么需要面向切面编程 如果在一个类或者多个类的多个业务逻辑方法中, 在开始,结尾部分包含功能相同的代码称之为横切关注点也叫切面, 这种结构可能符合传统的面向对象编程&#xff08;OOP&#xff09;的封装特性, 但可能导致代码难以维护和扩展。 面向切面编…

Python 如何进行自然语言处理(NLTK, SpaCy)

自然语言处理&#xff08;Natural Language Processing, NLP&#xff09;是计算机科学和人工智能的一个重要领域&#xff0c;旨在实现计算机对人类语言的理解和处理。在Python中&#xff0c;有许多工具和库可以用于自然语言处理&#xff0c;其中最流行的两个是NLTK&#xff08;…

【Python脚本】定时任务脚本实现、自动关机等功能脚本实现(保姆篇)

文章目录 功能描述源码分析依赖参数配置数据校验多线程并发执行定时任务注册自动关机主程序 源码整合本篇小结 更多相关内容可查看 功能描述 需要python环境&#xff0c;详情可看主页python相关文章【Python】从0开始写脚本、Selenium详细教程、附源码案例&#xff08;保姆篇&…

3dsMax模型展开UV之后无法删除,3dsmax删除模型上已经展开的UV

3dsmax展开UV之后如何删除UV 方法二 如果不能重置UV通道&#xff0c;在实用工具》更多工具》UVW移除&#xff0c;选中模型&#xff0c;点击UVW移除&#xff0c;移除模型的UVW。

机器人抓取与操作的挑战与进展——挑战赛角度

从竞赛中看机器人抓取与操作的挑战与进展 前言一、国际机器人竞赛有哪些&#xff1f;二、感知方面的挑战与进展二、抓取方面的挑战与进展三、操作方面的挑战与进展总结 前言 本文根据最近的机器人抓取和操作挑战赛 (Robotic Grasping andManipulation Competitions (RGMCs))&a…

OCR图片矫正、表格检测及裁剪综合实践

问题描述 实际工程中&#xff0c;我们经常需要对图片进行预处理&#xff0c;比如&#xff1a; 1、图片是倾斜的 2、图片背景需要处理掉 3、图片的公章需要剔除 4、图片过暗&#xff0c;过亮 5、图片表格检测 6、图片表格版面分析 。。。。。。等等各种情况。 结果展示…

解决PuppeteerSharp生成PDF颜色问题的最佳实践

在现代网络开发中&#xff0c;使用爬虫技术生成PDF文件已成为一种常见需求。然而&#xff0c;开发者经常会遇到一些棘手的问题&#xff0c;其中之一便是使用PuppeteerSharp生成PDF时颜色丢失的问题。本篇文章将概述如何解决这一问题&#xff0c;并提供最佳实践和相关代码示例。…