OpenCV的常用数据类型

news2024/9/27 17:36:31

        OpenCV涉及的常用数据类型除包含C++的基本数据类型,如:char、uchar,int、unsigned int,short 、long、float、double等数据类型外, 还包含Vec,Point、Scalar、Size、Rect、RotatedRect、Mat等类。C++中的基本数据类型不需再做说明下面重点介绍一下OpenCV中特有的与数据或数据处理相关的常用类。

Vec类

        Vec类是表示固定长度向量的模板类。它与vector相似,如初始化,元素访问等,与vector不同的是: 因Vec试固定长度向量模板类,在声明实例化时对象时,除指定类型外,还得指定长度,在声明vector实例化对象时,除需指定类型外,长度则不是必需的。另外,Vec对象除可以赋值运算符外,Vec对象还可以直接参与“算术运算”,而vector对象虽然可以使用赋值运算符,但不能直接参与“算术运算”。

        OpenCV中已经预定义了多个可以直接使用的Vec类型别名,如下:

        typedef Vec< uchar, 2 >  cv::Vec2b

        typedef Vec< uchar, 3 >  cv::Vec3b

        typedef Vec< uchar, 4 >  cv::Vec4b

        typedef Vec< short, 2 >  cv::Vec2s

        typedef Vec< short, 3 >  cv::Vec3s

        typedef Vec< short, 4>  cv::Vec4s

        typedef Vec< ushort, 2 >  cv::Vec2w

        typedef Vec< ushort, 3>  cv::Vec3w

        typedef Vec< ushort, 24>  cv::Vec4w

        typedef Vec< int, 2 >  cv::Vec2i

        typedef Vec< int, 3 >  cv::Vec3i

        typedef Vec< int, 4 >  cv::Vec4i

        typedef Vec< int, 6 >  cv::Vec6i

         typedef Vec< int, 8>  cv::Vec8i

        typedef Vec< float, 2 >  cv::Vec2f

        typedef Vec< float, 3 >  cv::Vec3f

        typedef Vec< float, 4>  cv::Vec4f

        typedef Vec< float, 6 >  cv::Vec6f

        typedef Vec< double, 2 >   cv::Vec2d

        typedef Vec< double, 3>     cv::Vec3d

        typedef Vec< double, 4 >     cv::Vec4d

        typedef Vec< double, 6 >     cv::Vec6d

        现在以实例演示一下Vector与Vec用法上的区别。下面程序,编译是不会出错的。

如果修改一下,加入算术运算代码, 如下:

可以看出·还没有编译,就·有·错误·提示·,说明vector对象·是不可以与常数相乘的。

Vec类型对象可以与标量进行乘除,下面的程序则可以通过编译,不会报错:

该程序试运行,结果如下:

需注意的是,Vec对象的算术运算并非真正数学上的算术运算,只是重载了算术运算符。Vec实例化对象可以被标量乘或除,结果是Vec对象的每一个元素都被标量乘或除。Vec对象可以做乘数、被乘数、被除数,但不可做除数。下面是一个Vec与标量乘、除的示例程序代码:

试运行,结果如下:

Vec对象间可以做“+”、“-”运算,运算的Vec对象的类型及长度须相同。下面是一个Vec对象“+”、“-”运算的示例程序:

试运行,结果如下:

Vec对象的乘积 Vec对象可以相乘,存在乘积、点积与叉积之分。Vec对象要进行乘运算也需类型与长度相同,不符合乘法交换律。下面是一个Vec对象相乘、点积、差积的示例程序: 

试运行,结果如下: 

Point(点)类

         Ponit类也是一个模版类.

        template<typename _Tp>
        class cv::Point_< _Tp >

Template class for 2D points specified by its coordinates x and y.

        template<typename _Tp>
        class cv::Point3_< _Tp >

Template class for 3D points specified by its coordinates xy and z.。

        Point类与MFC中的CPoint类似,OpenCV的Point类可以看作是存放2个或3个int或float值的容器,Point包含的值即点的坐标。点有二维点与三位点,OpenCV中按数据Point类型不同及维度不同预定义了:Point、Point2d、Point2i,Point2f、Pointe3d、Point3i、Point3f。

        typedef Point_<int> cv::Point2i

        typedef Point_<float> cv::Point2f

        typedef Point_<double> cv::Point2d

        typedef Point2i cv::Point

        typedef Point3_<double> cv::Point3d

        typedef Point3_<float> cv::Point3f

        typedef Point3_<int> cv::Point3i

        Point对象可以先声明再赋值,也可用构造函数构造Point对象并初始化。Point 也可被标量乘除、Point对象间也可加减、Point对象间也可求叉积、点积。下面以实例演示Point对象声明、初始化、及其它运算。下面是演示程序的代码:

// OpenCVBaseData.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

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

using namespace cv;
using namespace std;

int main()
{
    Point p1;
    p1.x = 100;
    p1.y = 100;
    Point p2(200, 100);

    Point2d p2d1(100,127);
    Point2d p2d2(10, 123);

    Point2i p2i1(500, 350);
    Point2i p2i2(00, 310);

    Point2f p2f1(13.5, 24.7);
    Point2f p2f2(350.0, 270.3);

    Point3d p3d1(15, 25, 35);
    Point3d p3d2(55, 85, 0);

    Point3i p3i1(351, 227, 158);
    Point3i p3i2(11, 127, 18);

    Point3f p3f1(153.5, 163.1, 191.9);
    Point3f p3f2(1003, 2465, 381);

    Point p3,p4;
    Point2d p2d3, p2d4;
    Point2i p2i3, p2i4;
    Point2f p2f3, p2f4;

    Point3d p3d3, p3d4;
    Point3i p3i3, p3i4;
    Point3f p3f3, p3f4;

    p3 = p1 + p2;
    cout << "p3:" << endl;
    cout << p3 << endl;

    p4 = p1 * 2;
    cout << "p4:" << endl;
    cout << p4 << endl;
    cout << p1.dot(p2) << endl;
    cout << p4.cross(p1) << endl;
    cout << p4.ddot(p2) << endl;

    p2d3 = p2d1 / 2;
    p2d4 = p2d1 - p2d2;
    
    cout << "p2d3:" << endl;
    cout << p2d3 << endl;
    cout << "p2d4:" << endl;
    cout << p2d4 << endl;
    cout << p2d4.ddot(p2d1) << endl;
    cout << p2d4.dot(p2d1) << endl;
    cout << p2d4.cross(p2d1) << endl;

    p2i3 = p2i1 / 2;
    p2i4 = p2i1 - p2i2;

    cout << "p2i3:" << endl;
    cout << p2i3 << endl;
    cout << "p2i4:" << endl;
    cout << p2i4 << endl;
    cout << p2i4.ddot(p2i1) << endl;
    cout << p2i4.dot(p2i1) << endl;
    cout << p2i4.cross(p2i1) << endl;

    p2f3 = p2i1 / 2;
    p2f4 = p2i1 - p2i2;

    cout << "p2f3:" << endl;
    cout << p2f3 << endl;
    cout << "p2f4:" << endl;
    cout << p2f4 << endl;
    cout << p2f4.ddot(p2f1) << endl;
    cout << p2f4.dot(p2f1) << endl;
    cout << p2f4.cross(p2f1) << endl;

    p3d3 = p3d1 / 2;
    p3d4 = p3d1 - p3d2;

    cout << "p3d3:" << endl;
    cout << p3d3 << endl;
    cout << "p3d4:" << endl;
    cout << p3d4 << endl;
    cout << p3d4.ddot(p3d1) << endl;
    cout << p3d4.dot(p3d1) << endl;
    cout << p3d4.cross(p3d1) << endl;

    p3i3 = p3i1 / 2;
    p3i4 = p3i1 - p3i2;

    cout << "p3i3:" << endl;
    cout << p3i3 << endl;
    cout << "p3i4:" << endl;
    cout << p3i4 << endl;
    cout << p3i4.ddot(p3i1) << endl;
    cout << p3i4.dot(p3i1) << endl;
    cout << p3i4.cross(p3i1) << endl;

    p3f3 = p3i1 / 2;
    p3f4 = p3i1 - p3i2;

    cout << "p3f3:" << endl;
    cout << p3f3 << endl;
    cout << "p3f4:" << endl;
    cout << p3f4 << endl;
    cout << p3f4.ddot(p3f1) << endl;
    cout << p3f4.dot(p3f1) << endl;
    cout << p3f4.cross(p3f1) << endl;

    waitKey(0);
    return 0;
}

试运行,结果如下:

OpenCV的点对象加、减运算需是相同类型及相同维度,而叉积与点积运算,则需是相同维度的Point才能进行。

Scalar(标量)类

        Scalar类(标量类)实际上是一个四维双精度向量类。Scalar的公有成员函数如下:

Scalar ()=default

Scalar (double v0)

Scalar (double v0, double v1, double v2=0, double v3=0)

const double &  operator[] (int i) const

double & operator[] (int i)

前三个为构造函数,后面两个为[]操作符重载函数。

Scalar有一个静态工有成员函数,如下:

static Scalar  all (double v0)

Scalar有一个公有属性,如下:

double val [4] = {0}

下面以实例演示Scalar对象创建,及公有属性的访问等。示例程序的代码如下:

// OpenCVBaseData.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

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

using namespace cv;
using namespace std;

int main()
{
    Scalar s1= Scalar();
    Scalar s2;
    s1[0] = 125;
    s1[1] = 125;
    s1[2] = 125;
    s1[3] = 0;
    s2 = s1.all(111);
    cout << "s1;  " << s1 << endl;
    cout << "s2;  " << s2 << endl;

    Scalar s3(127.0);
    cout << "s3;  " << s3 << endl;

    Scalar s4(120,255,110,0);
    cout << "s4;  " << s4 << endl;

    double d1, d2;
    d1 = s4.val[0];
    d2 = s4[3];
    cout << "d1: " << d1 <<endl;
    cout << "d2: " << d2 << endl;


    waitKey(0);
    return 0;
}

试运行,结果如下:

Size(尺寸)类 

        Size类比较简单,它有两个公有属性变量width、height。Size类重载了赋值操作符“=”。Size类的构造函数如下:

       Size ()=default

       Size (int _width, int _height)

       Size (const cv::Size &other)

Size因数据类型不同又可细分为:Size2dSize2iSize2f。下面以实例演示Size对象声明及初始化等操作。实例程序代码如下:

// OpenCVBaseData.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

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

using namespace cv;
using namespace std;

int main()
{
    Size s1 = Size();
    s1.width = 100;
    s1.height = 150;

    Size s2(110, 330);
    Size s3(s1);
    cout << "s1:  " << s1 << endl;
    cout << "s2:  " << s2 << endl;
    cout << "s3:  " << s3 << endl;

    Size2d s2d1(100,200);
    Size2i s2i1(1000, 2000);
    Size2f s2f1(1.00, 2.00);
    cout << "s2d1:  " << s2d1 << endl;
    cout << "s2i1:  " << s2i1 << endl;
    cout << "s2f1:  " << s2f1 << endl;
    

    waitKey(0);
    return 0;
}

试运行,结果如下:

Rect(矩形)类 

Rect类中以矩形的左上角坐标及矩形宽度与高度来定义一个矩形。Rect类共有4个公有属性变量:int x,int y,int  _width, int  _height。Rect类重载了赋值操作符“=”。Rect类的构造函数如下:

Rect ()=default

Rect (int _x, int _y, int _width, int _height)

       Rect (const cv::Rect &other)

       因数据类型不同,同样也有Rect2dRect2iRect2f

可是用Point类的inside函数判定一个点是否在矩形内。下面以实例演示,Rect类对象声明、初始化等。示例程序的代码如下:

// OpenCVBaseData.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

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

using namespace cv;
using namespace std;

int main()
{
    Rect rec1(0, 0, 100, 100);
    Rect rec2(rec1);
    Rect rec3 = rec2;
    cout << "rec1:  " << endl;
    cout << "x:  " << rec1.x << "  " << "y:  " << rec1.y << "  " << "width:  " << rec1.width << "  " << "height:  " << rec1.height << endl;
    cout << "rec2:  " << endl;
    cout << "x:  " << rec2.x << "  " << "y:  " << rec2.y << "  " << "width:  " << rec2.width << "  " << "height:  " << rec2.height << endl;

    Rect2d rec2d1(0, 0, 233, 233);
    Rect2i rec2i1(0, 0, 500, 500);
    Rect2f rec2f1(0, 0, 235.1, 500.0);
    Point p1(50, 250);
    if (p1.inside(rec2d1))
        cout << "p1 is inisde of rec2d1 " << endl;
    else
        cout << "p1 is not inisde of rec2d1 "<< endl;

    if (p1.inside(rec2i1))
        cout << "p1 is inisde of rec2i1 " << endl;
    else
        cout << "p1 is not inisde of rec2i1 " << endl;

    if (p1.inside(rec2f1))
        cout << "p1 is inisde of rec2f1 " << endl;
    else
        cout << "p1 is not inisde of rec2f1 " << endl;
    

    waitKey(0);
    return 0;
}

试运行,结果如下:

        Rect对象可以进行“==”判定,“|”运算、“&”运算。下面以实例做演示,演示代码如下: 

// OpenCVBaseData.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

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

using namespace cv;
using namespace std;

int main()
{
    Rect rec1(0, 0, 300, 300);
    Rect rec2(100, 100, 500, 500);
    if (rec1 == rec2)
        cout << "rec1 equals rec2" << endl;
    else
        cout << "rec1 does not equal rec2" << endl;

    Rect rec3 = rec1 & rec2;
    cout << rec3 << endl;

    Rect rec4 = rec1 | rec2;
    cout << rec4 << endl;

    waitKey(0);
    return 0;
}

试运行,结果如下:

RotatedRect(旋转矩形)类 

RotatedRect类与Rect类的不同点是,Rect类所表示的矩形是水平放置的,而RotatedRect类所表示的矩形则是以任意角度放置的,相当于在Rect表示的矩形基础上再旋转一个角度。

RotatedRect类的公有成员函数有一下几个:

RotatedRect ()

RotatedRect (const Point2f &center, const Size2f &size, float angle)

参数:center 矩形的质心,size 矩形的长宽尺寸,angle 旋转角度(顺时针方向旋转)

RotatedRect (const Point2f &point1, const Point2f &point2, const Point2f &point3)

参数: point1 矩形的第一个点,point2 矩形的第二个点,point3 矩形的第三个点,

Rect boundingRect () const

返回包含旋转矩形对象所表示旋转矩形的最小矩形,数据类型为int

Rect<float> boundingRect2f () const

返回包含旋转矩形对象所表示旋转矩形的最小矩形,数据类型为float

void points (Point2f pts[]) const

用旋转矩形对象所表示矩形的角点填充Point2f 点数组

void points (std::vector< Point2f > &pts) const

用旋转矩形对象所表示矩形的角点填充Point2f 点数组

RotatedRect类的公有属性成员变量有一下几个:

float angle 旋转角度,以度表示

Pointe2f center  矩形的质心

Size2f   size    代表矩形长宽的尺寸

       下面以实例演示RotatedRect对象构造及其它成员函数的用法。示例代码如下:

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

using namespace cv;
using namespace std;

int main()
{
    Mat background(600, 1200, CV_8UC3, Scalar(127, 127, 127));
    string vertex_names[4] = { "1","2","3","4" };
    Point2f vertices[4];

    RotatedRect rRect = RotatedRect(Point2f(600, 300), Size2f(100, 50), 30);
    rRect.points(vertices);

    for (size_t i = 0; i < 4; i++)
    {
        line(background, vertices[i], vertices[(i + 1) % 4], Scalar(0, 0, 255), 1);
        putText(background, vertex_names[i], vertices[i], FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 255, 0));
    }

    //Rect rec = rRect.boundingRect();
    Rect2f rec = rRect.boundingRect2f();
    rectangle(background, rec, Scalar(255, 0, 0), 1, 8, 0);

    imshow("Image", background);

    
    RotatedRect rRect1(Point2f(100, 100), Point2f(400, 100), Point2f(400, 300));
    cout <<"rRect1 angle:  "<< rRect1.angle << endl;
    cout << "rRect1 center:  " << rRect1.center << endl;
    cout << "rRect1 size" << rRect1.size << endl;
    
    waitKey(0);
    return 0;
}

试运行,结果如下:

Mat 类 

        Mat类在前面的文章中已经详细介绍这里不再做说明。这里介绍一下Mat对象矩阵数据的位操作及矩阵运算。假如一个Mat对象存储了一副RGB图像,如何获取或改变图像中某一像素的值呢?要做到这一点可以用以下几种

        1. 使用Mat类的成员函数at。

        2,使用Mat内部数据指针ptr。

        3. 使用Mat的数据矩阵的数据指针data。

        4. 使用迭代器

下面用一个实例来演示以上几种Mat数据位操作方法。示例代码如下:

// OpeCVSharp.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


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

using namespace cv;
using namespace std;

int main()
{
    Mat src = imread("1.jpg");
    if (src.empty())
    {
        cout << "Cann't load image!" << endl;
        return -1;
    }
    cout <<"src.cols:" << src.cols << endl;
    cout << "src.rows:" << src.rows << endl;
    cout << "src channels:" << src.channels() << endl;
    cout << "src type:" << src.type() << endl;

    //获取第0排0列像素BGR值
    uchar b = src.at<uchar>((0, 0), 0);
    uchar g = src.at<uchar>((0, 0), 1);
    uchar r = src.at<uchar>((0, 0), 2);
    cout << "BGR:" << (int)b << "  " << (int)g << "  " << (int)r << endl;

    uchar* puchar = src.ptr(0, 0);
    uchar b1 = puchar[0];
    uchar g1 = puchar[1];
    uchar r1 = puchar[2];
    cout << "BGR:" << (int)b1 << "  " << (int)g1 << "  " << (int)r1 << endl;

    uchar b2 = src.data[0];
    uchar g2 = src.data[1];
    uchar r2 = src.data[2];
    cout << "BGR:" << (int)b2 << "  " << (int)g2 << "  " << (int)r2 << endl;

    //改变第0排0列像素BGR值
    src.at<uchar>((0, 0), 0) = 0;
    src.at<uchar>((0, 0), 1) = 0;
    src.at<uchar>((0, 0), 1) = 255;

    /*
    puchar[0] = 0;
    puchar[0] = 1;
    puchar[0] = 255;
    */

    /*
    src.data[0] =0;
    src.data[1] = 0;
    src.data[2] =255;
   */

    //imshow("src", src);
    
    waitKey(0);
    return 0;
}

试运行,结果如下:

Mat对象实质上是数据矩阵,当然可以进行矩阵运算。这里不做全面介绍,仅介绍两个有趣的运算,与常数相乘及与常数向加。

        先用实例演示与常数相乘,示例代码如下:

// OpeCVSharp.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


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

using namespace cv;
using namespace std;

int main()
{
    Mat src = imread("1.jpg");
    if (src.empty())
    {
        cout << "Cann't load image!" << endl;
        return -1;
    }
    cout <<"src.cols:" << src.cols << endl;
    cout << "src.rows:" << src.rows << endl;
    cout << "src channels:" << src.channels() << endl;
    cout << "src type:" << src.type() << endl;
    imshow("src", src);

    src *= 1.5;
    imshow("src new", src);

    src *= 0.5;
    imshow("src new1", src);

    waitKey(0);
    return 0;
}

 试运行,结果如下:

可以看出存有图像的Mat对象乘以一个大于1的常数将使图像变亮,乘以一个小于1的常数使图像变暗。不难想象,该Mat对象除以一个常数将会发生什么现象。

        再演示一下Mat对象加、减以一个常数,示例代码如下:

// OpeCVSharp.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


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

using namespace cv;
using namespace std;

int main()
{
    Mat src = imread("1.jpg");
    if (src.empty())
    {
        cout << "Cann't load image!" << endl;
        return -1;
    }
    cout <<"src.cols:" << src.cols << endl;
    cout << "src.rows:" << src.rows << endl;
    cout << "src channels:" << src.channels() << endl;
    cout << "src type:" << src.type() << endl;
    imshow("src", src);

    src += 20;
    imshow("src new", src);

    src -= 40;
    imshow("src new1", src);

    waitKey(0);
    return 0;
}

试运行,结果如下:

        可以看出,加一个常数使图像变得更蓝,减以一个常数使图像变黄,说明加、减都作用在像素的B通道上。 上面是用彩色图做演示,如果把彩色图转换成灰度图结果又会如何呢?再用实例演示一下,下面是演示的示例代码:

// OpeCVSharp.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


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

using namespace cv;
using namespace std;

int main()
{
    Mat src = imread("1.jpg");
    if (src.empty())
    {
        cout << "Cann't load image!" << endl;
        return -1;
    }
    cout <<"src.cols:" << src.cols << endl;
    cout << "src.rows:" << src.rows << endl;
    cout << "src channels:" << src.channels() << endl;
    cout << "src type:" << src.type() << endl;
   // imshow("src", src);

    cvtColor(src, src, COLOR_BGR2GRAY);
    imshow("src", src);

    src += 60;
    imshow("src new", src);

    src -= 80;
    imshow("src new1", src);

    waitKey(0);
    return 0;
}

试运行,结果如下:

可以看出,对含灰度图的Mat对象加一个 正数,图像会变量,减一个正数图像会变暗。

下面再演示一下使用迭代器是图像变亮,示例代码如下:

// OpeCVSharp.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。


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

using namespace cv;
using namespace std;

int main()
{
    Mat src = imread("1.jpg");
    if (src.empty())
    {
        cout << "Cann't load image!" << endl;
        return -1;
    }
    imshow("src", src);

    /*
    Mat kernel = (Mat_<float>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);

    filter2D(src, src, src.depth(), kernel);
    imshow("src new", src);
    */

    //让图像变亮
    MatIterator_<Vec3b> itstart = src.begin<Vec3b>();
    MatIterator_<Vec3b> itend = src.end<Vec3b>();
    int temp = src.rows * src.cols;
    for (; itstart != itend; itstart++)
    {
        (*itstart)[0] = saturate_cast<uchar>((*itstart)[0] + 50);
        (*itstart)[1] = saturate_cast<uchar>((*itstart)[1] + 50);
        (*itstart)[2] = saturate_cast<uchar>((*itstart)[2] + 50);
    }

    imshow("src new", src);

    waitKey(0);
    return 0;
}

试运行结果如下:

 

本文到此结束,示例是基于OpenCV4.8(opencv目录位于d盘根目录下)及VS2022。

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

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

相关文章

redisson解决redis服务器的主从一致性问题

redisson解决redis的主节点和从节点一致性的问题。从而解决锁被错误获取的情况。 实际开发中我们会搭建多台redis服务器&#xff0c;但这些服务器分主次&#xff0c;主服务器负责处理写的操作&#xff08;增删改&#xff09;&#xff0c;从服务器负责处理读的操作&#xff0c;…

全国保护性耕作/常规耕作农田分类数据集

基于Sentinel-2遥感产品&#xff0c;使用来自文献调研和目视解译产生的保护性/常规耕作样本点&#xff0c;通过交叉验证方法训练随机森林分类器&#xff0c;生成了2016-2020年全国保护性耕作/常规耕作农田分类数据集。分类代码&#xff1a;0值代表非农田&#xff0c;1值表示第一…

掌握React中的useEffect:函数组件中的魔法钩子

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Django 模版基本语法

Django学习笔记 模版语法 本质&#xff1a;在HTML中写一些占位符&#xff0c;由数据对这些占位符进行替换和处理。 views.py def page2(request):#定义一些变量将变量传送给templates中的html文件name1 sallyname2 yingyinghobbys [swimming,badminton,reading]person {…

数学建模【对粒子群算法中惯性权重和学习因子的改进】

一、改进原因 这是前面 数学建模【粒子群算法】 中的一部分&#xff0c;这里提到了w存在的一些问题&#xff0c;那么本篇介绍一些方法对w和因子进行一些改进&#xff0c;提高粒子群算法的效率和准确度。 二、改进方法 1.线性递减惯性权重 惯性权重w体现的是粒子继承先前的速度…

如何获取用户请求的真实ip,并返回访问者的ip地理位置?node,vue

一、获取真实IP 方式1、前端调用免费公共接口获取 前端获取访问者的真实的外网ip,可以通过调用接口https://api.ipify.org/来获取。你也可以直接在网页上访问它来看自己的外网ip。 ipify介绍&#xff1a; ipify是一个免费的公共 API&#xff0c;用于获取设备的公共 IP 地址。…

备考2025年AMC8数学竞赛:吃透2000-2024年600道AMC8真题就够

我们继续来随机看五道AMC8的真题和解析&#xff0c;根据实践经验&#xff0c;对于想了解或者加AMC8美国数学竞赛的孩子来说&#xff0c;吃透AMC8历年真题是备考最科学、最有效的方法之一。 即使不参加AMC8竞赛&#xff0c;吃透了历年真题600道和背后的知识体系&#xff0c;那么…

conda pack环境迁移并下载安装离线包

背景 训练服务器为了安全起见&#xff0c;限制不能联网&#xff0c;无法直接创建虚拟环境及安装模型的依赖库&#xff0c;所以需要把另一台测试服务器已经部署好的虚拟环境迁移到训练服务器上&#xff0c;并在不能联网的情况下安装一些离线包。过程记录如下记录。 一、环境迁移…

指针篇章(3)-(指针之间的区别)

学习目录 ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————…

微信小程序开发系列(二十六)·小程序运行机制(启动、前后台状态、挂起、销毁)和小程序更新机制

目录 1. 小程序运行机制 1.1 启动 1.2 前台和后台状态 1.3 挂起 1.4 销毁 2. 小程序更新机制 1. 小程序运行机制 1.1 启动 小程序启动可以分为两种情况&#xff0c;一种是冷启动&#xff0c;一种是热启动。 冷启动&#xff1a;如果用户首次打开&#xff0c;或小…

mysql的trace追踪SQL工具,进行sql优化

trace是MySQL5.6版本后提供的SQL跟踪工具&#xff0c;通过使用trace可以让我们明白optimizer&#xff08;优化器&#xff09;如何选择执行计划。 注意&#xff1a;开启trace工具会影响mysql性能&#xff0c;所以只适合临时分析sql使用&#xff0c;用完之后请立即关闭。 测试数…

电脑中缺失EMP.dll文件怎么办,解决EMP.dll丢失问题的有效方法分享

当你的电脑出现由于找不到emp.dll无法继续执行代码的提示&#xff0c;那你要怎么办呢&#xff1f;其实解决方法还是挺多的&#xff0c;今天就来给大家详细的说说emp.dll这方面的信息吧。 一、电脑为什么会出现emp.dll丢失 不完全卸载软件&#xff1a;在卸载程序时&#xff0c;…

小迪安全37WEB 攻防-通用漏洞XSS 跨站权限维持钓鱼捆绑浏览器漏洞

#XSS跨站系列内容:1. XSS跨站-原理&分类&手法 XSS跨站-探针&利用&审计XSS跨站另类攻击手法利用 XSS跨站-防御修复&绕过策略 #知识点&#xff1a; 1、XSS 跨站-另类攻击手法分类 2、XSS 跨站-权限维持&钓鱼&浏览器等 1、原理 指攻击者利用…

可商用的HuoCMS建站系统,基于thinkphp内核且免费开源

HuoCMS是一套内容管理系统&#xff0c;同时也是一套适用于企业官网建设的系统&#xff0c;能够帮助用户快速搭建个人网站。满足企业站、外贸站、个人博客等多种建站需求。HuoCMS的优势在于可以通过统一后台管理多个网站的内容&#xff0c;方便维护和共享不同内容在不同网站上的…

关于playbook中when条件过滤报The conditional check ‘result|failed‘ failed的问题

问题现象 在使用plabook中的when做过滤脚本如下&#xff1a; --- - hosts: realserversremote_user: roottasks:- name: Check if httpd service is runningcommand: systemctl status httpdregister: resultignore_errors: True- name: Handle failed service checkdebug:ms…

离线数仓(六)【ODS 层开发】

前言 1、ODS 层开发 ODS层的设计要点如下&#xff1a; &#xff08;1&#xff09;ODS层的表结构设计依托于从业务系统同步过来的数据结构&#xff08;JSON/CSV/TSV&#xff09;。 &#xff08;2&#xff09;ODS层要保存全部历史数据&#xff0c;故其压缩格式应选择高压缩比的…

Android 学习之追踪应用的安装情况

先上结论&#xff0c;急用的话直接看结论 结论一、借助 API 读取安装信息&#xff0c;然后上报二、借助手动埋点&#xff0c;然后上报三、对比 前提过程 结论 一、借助 API 读取安装信息&#xff0c;然后上报 通过 PackageManager 的 API&#xff0c;我们可以得知自身应用安装…

基于VSCode安装Node.js开发环境

根据官网介绍&#xff0c;Node.js 是一个免费的、开源的、跨平台的JavaScript实时运行环境&#xff0c;允许开发人员在浏览器之外编写命令行工具和服务器端脚本. Node.js框架由于是采用JavaScript语法进行调用的&#xff0c;因此Node.js环境除了用来编写调试Node.js代码&#…

2024 年排名前 5 名的 Mac 数据恢复软件分享

如果您已经在 Mac 上丢失了数据并且正在寻找恢复数据的方法&#xff0c;那么您来对地方了。互联网上有超过 50 个适用于 Mac 的数据恢复程序。哪个是最好的 Mac 数据恢复软件&#xff1f;不用担心。本文列出了 5 款 Mac 数据恢复软件&#xff0c;可帮助您在 Mac OS 下恢复丢失的…

jvm八股

文章目录 运行时数据区域Java堆对象创建对象的内存布局对象的访问定位句柄直接指针 GC判断对象是否已死引用计数算法可达性分析算法 引用的类别垃圾收集算法分代收集理论标记清除算法标记复制算法标记整理算法 实现细节并发的可达性分析 垃圾收集器serial收集器ParNew收集器Par…