视觉培训3 装甲板识别

OpenCv的HSV颜色空间学习

学习的网站

虽然我们这张图的方框并不是彩色的,但是以后肯定会遇到彩色的问题所以先学习一下

H——Hue即色相,就是我们平时所说的红、绿,如果你分的更细的话可能还会有洋红、草绿等等;在HSV模型中,用度数来描述色相,其中红色对应0度,绿色对应120度,蓝色对应240度。

视觉培训3 装甲板识别

S——Saturation即饱和度,色彩的深浅度(0-100%) ,对于一种颜色比如红色,我们可以用浅红——大红——深红——红得发紫等等语言来描述它,对应在画水彩的时候即一种颜料加上不同分量的水形成不同的饱和度。

V——Value即色调,纯度,色彩的亮度(0-100%) ,这个在调整屏幕亮度的时候比较常见。

视觉培训3 装甲板识别

注:在模型2中:

H是色彩点在对应圆形切面上与红色半径(对于H=0度)所形成的圆心角。

V是色彩点所在圆形切面到圆锥顶点的距离。在顶面上V=1 顶点V=0

S是色彩点到所在圆形切面圆心的距离与该圆半径的比例值,在圆锥表面上S=1,在圆心处S=0

有如下结论:

当S=1 V=1时,H所代表的任何颜色被称为纯色;
当S=0时,即饱和度为0,颜色最浅,最浅被描述为灰色(灰色也有亮度,黑色和白色也属于灰色),灰色的亮度由V决定,此时H无意义;
当V=0时,颜色最暗,最暗被描述为黑色,因此此时H(无论什么颜色最暗都为黑色)和S(无论什么深浅的颜色最暗都为黑色)均无意义。

与上述HSV颜色系统不同的是,如果直接使用OpenCV中cvtColor函数,并设置参数为CV_BGR2HSV,那么所得的H、S、V值范围分别是[0,180),[0,255),[0,255),而非[0,360],[0,1],[0,1];这时我们可以查下面的表格来确定颜色的大致区间。

视觉培训3 装甲板识别

可以用以下代码查看:

Mat src = imread("test.jpg");
Mat hsv;
cvtColor(src, hsv, CV_BGR2HSV); //直接转换
cout<<hsv<<endl; 可以直接在控制台输出hsv查看结果< code></hsv<<endl;>

任务

下图为对包含装甲板的图像处理后得到的mask,对于该图,提取并筛选出装甲板两个灯柱的轮廓,并标出装甲板的中心。

视觉培训3 装甲板识别

先是根据东南大学的开源代码折腾了半天,一直没折腾出来,代码如下

cv::RotatedRect &adjustRec(cv::RotatedRect &rec)
{
    using std::swap;

    float &width = rec.size.width;
    float &height = rec.size.height;
    float &angle = rec.angle;

    while (angle >= 90.0)
        angle -= 180.0;
    while (angle < -90.0)
        angle += 180.0;

    if (angle >= 45.0)
    {
        swap(width, height);
        angle -= 90.0;
    }
    else if (angle < -45.0)
    {
        swap(width, height);
        angle += 90.0;
    }

    return rec;
}

int main(int argc, char **argv)
{
    Mat dst = imread("C:/Users/86139/Desktop/target.png");
    vector<vector<point>> Light_Contour; // &#x53D1;&#x73B0;&#x7684;&#x8F6E;&#x5ED3;
    vector<rotatedrect> vContour;
    vector<rotatedrect> vRec;

    findContours(dst, Light_Contour, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); // &#x5BFB;&#x627E;&#x8F6E;&#x5ED3;

    for (int64 i = 0; i < Light_Contour.size(); i++)
    {
        float Light_Contour_Area = contourArea(Light_Contour[i]);

        if (Light_Contour_Area < 15 || Light_Contour[i].size() <= 10) continue; 用椭圆拟合区域得到外接矩形 rotatedrect light_rec="fitEllipse(Light_Contour[i]);" 这里限制了角度 if (light_rec.angle> 10)
            continue;

        // &#x957F;&#x5BBD;&#x6BD4;&#x548C;&#x8F6E;&#x5ED3;&#x9762;&#x79EF;&#x6BD4;&#x9650;&#x5236;
        if (Light_Rec.size.width / Light_Rec.size.height > 1.5 || Light_Contour_Area / Light_Rec.size.area() < 0.5)
            continue;
        // &#x6269;&#x5927;&#x706F;&#x67F1;&#x7684;&#x9762;&#x79EF;
        Light_Rec.size.height *= 1.1;
        Light_Rec.size.width *= 1.1;
        vContour.push_back(Light_Rec);
    }

    for (size_t i = 0; i < vContour.size(); i++)
    {
        for (size_t j = i + 1; j < vContour.size(); j++)
        {
            //&#x5224;&#x65AD;&#x662F;&#x5426;&#x4E3A;&#x76F8;&#x540C;&#x706F;&#x6761;
            float Contour_angle = abs(vContour[i].angle - vContour[j].angle); //&#x89D2;&#x5EA6;&#x5DEE;
            if (Contour_angle >= 7)
                continue;
            //&#x957F;&#x5EA6;&#x5DEE;&#x6BD4;&#x7387;
            float Contour_Len1 = abs(vContour[i].size.height - vContour[j].size.height) /
                                 max(vContour[i].size.height, vContour[j].size.height);
            //&#x5BBD;&#x5EA6;&#x5DEE;&#x6BD4;&#x7387;
            float Contour_Len2 = abs(vContour[i].size.width - vContour[j].size.width) /
                                 max(vContour[i].size.width, vContour[j].size.width);
            if (Contour_Len1 > 0.25 || Contour_Len2 > 0.25)
                continue;

            //&#x88C5;&#x7532;&#x677F;&#x7B5B;&#x9009;
            RotatedRect Rect;
            Rect.center.x = (vContour[i].center.x + vContour[j].center.x) / 2.; // x&#x5750;&#x6807;
            Rect.center.y = (vContour[i].center.y + vContour[j].center.y) / 2.; // y&#x5750;&#x6807;
            Rect.angle = (vContour[i].angle + vContour[j].angle) / 2.;          //&#x89D2;&#x5EA6;
            float nh, nw, yDiff, xDiff;
            nh = (vContour[i].size.height + vContour[j].size.height) / 2; //&#x9AD8;&#x5EA6;
            // &#x5BBD;&#x5EA6;
            nw = sqrt((vContour[i].center.x - vContour[j].center.x) * (vContour[i].center.x - vContour[j].center.x) + (vContour[i].center.y - vContour[j].center.y) * (vContour[i].center.y - vContour[j].center.y));
            float ratio = nw / nh;                                         //&#x5339;&#x914D;&#x5230;&#x7684;&#x88C5;&#x7532;&#x677F;&#x7684;&#x957F;&#x5BBD;&#x6BD4;
            xDiff = abs(vContour[i].center.x - vContour[j].center.x) / nh; // x&#x5DEE;&#x6BD4;&#x7387;
            yDiff = abs(vContour[i].center.y - vContour[j].center.y) / nh; // y&#x5DEE;&#x6BD4;&#x7387;
            if (ratio < 1.0 || ratio > 5.0 || xDiff < 0.5 || yDiff > 2.0)
                continue;
            Rect.size.height = nh;
            Rect.size.width = nw;
            vRec.push_back(Rect);
            Point2f point1;
            Point2f point2;
            point1.x = vContour[i].center.x;
            point1.y = vContour[i].center.y + 20;
            point2.x = vContour[j].center.x;
            point2.y = vContour[j].center.y - 20;
            int xmidnum = (point1.x + point2.x) / 2;
            int ymidnum = (point1.y + point2.y) / 2;
            Rect.center.x = filter(Rect.center.x, xmidnum, DELAT_MAX);
            Rect.center.y = filter(Rect.center.y, ymidnum, DELAT_MAX);
            Scalar color(rand() & 255, rand() & 255, rand() & 255);
            rectangle(dst, point1, point2, color, 2);
            circle(dst, Rect.center, 10, color);

            imshow("Rect", dst);
            waitKey(0);
        }
    }

    return 0;
}</=></rotatedrect></rotatedrect></vector<point>

在用cmake编译时遇到了:warning C4819: 该文件包含不能在当前代码页(936)中表示的字符

解决方法:

在CMakeList.txt中加入如下内容:

add_compile_options("$<$<c_compiler_id:msvc>:/utf-8>")
add_compile_options("$<$<cxx_compiler_id:msvc>:/utf-8>")</$<cxx_compiler_id:msvc></$<c_compiler_id:msvc>

且必须位于add_executable之前

还有一个基础知识错误:warning C4018: “

Original: https://blog.csdn.net/weixin_47259513/article/details/125923306
Author: 世界函数
Title: 视觉培训3 装甲板识别

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/701284/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球