工业缺陷检测项目实战(一)——基于opencv的工件缺陷检测C++实现

基于opencv的工件缺陷检测C++和python实现

作为研究生,每一个项目都很重要,这里给大家分享一个好入门项目,代码纯自己写,网上都是python的,但是有些企业要求C++编写项目,所以希望大家能学到东西。
一. 问题陈述
工件的展示,这是一个视频,然后工件一个个经过,要检测出哪个工件有缺陷,并且分类缺陷的种类。可以看到缺陷是不止一种。

工业缺陷检测项目实战(一)——基于opencv的工件缺陷检测C++实现
工业缺陷检测项目实战(一)——基于opencv的工件缺陷检测C++实现
二. 代码步骤
1.读取图像,转为灰度图并二值化
cvtColor(img, gray, COLOR_BGR2GRAY);
threshold(gray, thresh, 127, 255, THRESH_TOZERO_INV);、

2.寻找轮廓

std::vector<vec4i> hireachy;
std::vector<std::vector<point>> contours;
findContours(thresh, contours, hireachy, RETR_LIST, CHAIN_APPROX_NONE);
</std::vector<point></vec4i>

3.遍历轮廓,对工件圈进行统计,防止重复标记
原理是计算图像矩,可以确定图像的灰度中心,根据每个时刻每个工件的中心位置的变换,可以判断画面里是否出现新的工件。同时,也要记得更新每个时刻每个工件的位置。具体代码实现可以参考完整工程文件。这里贴出部分:

for (size_t cnt = 0; cnt < contours.size(); cnt++)
        {
            double area = contourArea(contours[cnt]); //&#x6C42;&#x8F6E;&#x5ED3;&#x9762;&#x79EF;(&#x5927;&#x7EA6;&#x7684;)
            if (area > 18000 & area < 28000)          //&#x628A;&#x5DE5;&#x4EF6;&#x5708;&#x51FA;&#x6765;
            {
                mu[cnt] = moments(contours[cnt], false); //&#x8BA1;&#x7B97;&#x56FE;&#x50CF;&#x77E9;&#xFF0C;&#x8868;&#x793A;&#x5DE5;&#x4EF6;&#x7684;&#x4F4D;&#x7F6E;
                //&#x8BA1;&#x7B97;&#x56FE;&#x50CF;&#x8D28;&#x5FC3;&#x4F4D;&#x7F6E;
                double cx = mu[cnt].m10 / mu[cnt].m00;
                double cy = mu[cnt].m01 / mu[cnt].m00;
                boundRect[cnt] = boundingRect(Mat(contours[cnt])); //&#x8BA1;&#x7B97;&#x5916;&#x63A5;&#x77E9;&#x5F62;

                new_object = true;
                //&#x901A;&#x8FC7;&#x8D28;&#x5FC3;&#x4F4D;&#x7F6E;&#x5224;&#x65AD;&#x89C6;&#x9891;&#x51FA;&#x73B0;&#x7684;&#x5DE5;&#x4EF6;&#x662F;&#x5426;&#x662F;&#x6700;&#x65B0;&#x7684;
                if (cx > 100) //&#x5DE5;&#x4EF6;&#x8981;&#x5168;&#x90E8;&#x51FA;&#x73B0;
                {
                    if (products.size() > 0) //&#x5224;&#x65AD;&#x51FA;&#x73B0;&#x7684;&#x5DE5;&#x4EF6;&#x662F;&#x4E0D;&#x662F;&#x65B0;&#x7684;
                    {
                        for (size_t i = 0; i < products.size(); i++)
                        {
                            //&#x5B58;&#x5728;&#x4E00;&#x4E2A;
                            if (fabs(cx - products[i].getX()) <= 35 && fabs(cy - products[i].gety()) <="35)" { new_object="false;" 更新位置参数 products[i].updatecoords(cx, cy, boundrect[cnt].x, boundrect[cnt].y, boundrect[cnt].width, boundrect[cnt].height); } if (new_object="=" true) product p(pid, cx, p.save_pic(img); products.emplace_back(p); p.count="pid;" defects="p.defect_detect();" 缺陷检测 pid +="1;" 圈出来 rectangle(img, boundrect[cnt].tl(), boundrect[cnt].br(), scalar(0, 0, 255), 2, 8, 0); code></=>

效果是这样:

工业缺陷检测项目实战(一)——基于opencv的工件缺陷检测C++实现

4.遍历轮廓,把工件圈出来,顺便保存调试,如下图。圈出来的原理也不难,其实就是通过函数

boundRect[cnt] = boundingRect(Mat(contours[cnt]));

计算外接矩形,就可以获得矩形的左上角和右下角坐标,就可以画了。效果如下:

工业缺陷检测项目实战(一)——基于opencv的工件缺陷检测C++实现
工业缺陷检测项目实战(一)——基于opencv的工件缺陷检测C++实现
工业缺陷检测项目实战(一)——基于opencv的工件缺陷检测C++实现

5.对每个框进行缺陷提取,原理依然是轮廓检测加面积判断。效果如下:

工业缺陷检测项目实战(一)——基于opencv的工件缺陷检测C++实现
工业缺陷检测项目实战(一)——基于opencv的工件缺陷检测C++实现
6.缺陷类型判断,这里利用直方图统计。即统计0-255中每个像素的个数,根据个数,转为百分比,接着我们设定一个阈值,就可以判断出缺陷类型。部分代码:
          //------------------------&#x76F4;&#x65B9;&#x56FE;&#x8BA1;&#x7B97;
            Mat hist;
            //&#x8BBE;&#x5B9A;&#x50CF;&#x7D20;&#x53D6;&#x503C;&#x8303;&#x56F4;
            int histSize = 256;
            float range[] = {0, 256};
            const float *histRanges = {range};
            // hist&#x7D22;&#x5F15;&#x4E3A;&#x50CF;&#x7D20;&#xFF0C;&#x503C;&#x4E3A;&#x50CF;&#x7D20;&#x70B9;&#x7684;&#x4E2A;&#x6570;
            calcHist(&resul, 1, 0, Mat(), hist, 1, &histSize, &histRanges, true, false);
            //-------------------------&#x5224;&#x65AD;&#x7F3A;&#x9677;
            float sum = 0;
            for (int i = 0; i < 256; i++)
            {
                float bin_val = hist.at<float>(i); //&#x904D;&#x5386;hist&#x5143;&#x7D20;&#xFF08;&#x6CE8;&#x610F;hist&#x4E2D;&#x662F;float&#x7C7B;&#x578B;&#xFF09;
                sum = sum + bin_val;               //&#x8BA1;&#x7B97;&#x603B;&#x7684;&#x4E2A;&#x6570;
            }
            // std::cout << "sum:"
            //           << sum << "\n";
            //&#x8BA1;&#x7B97;&#x5404;&#x4E2A;&#x50CF;&#x7D20;&#x70B9;&#x7684;&#x4E2A;&#x6570;&#x767E;&#x5206;&#x6BD4;
            for (int i = 0; i < 256; i++)
            {
                if (hist.at<float>(i) > 0) //&#x50CF;&#x7D20;&#x70B9;&#x4E2A;&#x6570;&#x5927;&#x4E8E;0&#x7684;&#x65F6;&#x5019;
                {
                    hist.at<float>(i) = hist.at<float>(i) / sum;
                }
                // std::cout << "hist:"
                //           << hist.at<float>(i) << "\n";
            }
            float hist_sum_scratch = 0;
            float hist_sum_blot = 0;
            for (int i = 90; i < 135; i++) //&#x6BD4;&#x8F83;&#x7070;&#x7684;
            {
                hist_sum_scratch = hist_sum_scratch + hist.at<float>(i);
            }
            std::cout << "hist_sum_scratch:"
                      << hist_sum_scratch << "\n";
            for (int i = 15; i < 90; i++) //&#x6BD4;&#x8F83;&#x9ED1;&#x7684;
            {
                hist_sum_blot = hist_sum_blot + hist.at<float>(i);
            }
            std::cout << "hist_sum_blot:"
                      << hist_sum_blot << "\n";
            if (hist_sum_scratch >= hist_sum_blot)
            {
                Defect d(1, boundRect[cnt].x, boundRect[cnt].y, boundRect[cnt].width, boundRect[cnt].height);
                Result.emplace_back(d);
                state = 1;
                std::cout << "&#x6B64;&#x5904;&#x7F3A;&#x9677;&#x5212;&#x75D5;"
                          << "\n";
            }
            if (hist_sum_scratch < hist_sum_blot)
            {
                Defect d(2, boundRect[cnt].x, boundRect[cnt].y, boundRect[cnt].width, boundRect[cnt].height);
                Result.emplace_back(d);
                state = 2;
                std::cout << "&#x6B64;&#x5904;&#x7F3A;&#x9677;&#x6C61;&#x6E0D;"
                          << "\n";
            }
</float></float></float></float></float></float></float>

到此就可以完成啦!!!

三. 最终效果:

工业缺陷检测项目实战(一)——基于opencv的工件缺陷检测C++实现
可以看到,会在终端打印相关消息

C++代码纯自己写,有多文件,花了一些时间总结,大家可以私信我拿代码
另外,也准备了python代码,需要的也可以私信我。

因为花费不少时间,所以希望大家给点报酬支持一下, 继续加油进入下一个实战项目分享

————————————补充内容———————————

由于很多小伙伴下载代码之后不知道怎么使用这代码,今天就补充一下。首先,我们需要安装 opencv与dlib,参考下我的另外一篇文章:
ubuntu20+dlib19.22+0pencv4.5.0的机器视觉算法之路(一).

1.删除buiild文件夹里面的 所有文件
2.路径打开到build, 执行

cmake ..

3.接着

make

4.执行

./result

搞定,完结,欢迎大家来学习,当作自己的一个项目,或者可以进一步去扩展成其他东西,懂的都懂。

Original: https://blog.csdn.net/weixin_39735688/article/details/121364796
Author: 夏融化了这季节
Title: 工业缺陷检测项目实战(一)——基于opencv的工件缺陷检测C++实现

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

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

(0)

大家都在看

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