基于opencv的工件缺陷檢測C++和python實現(xiàn)
作為研究生,每一個項目都很重要,這里給大家分享一個好入門項目,代碼純自己寫,網(wǎng)上都是python的,但是有些企業(yè)要求C++編寫項目,所以希望大家能學到東西。
一. 問題陳述
工件的展示,這是一個視頻,然后工件一個個經(jīng)過,要檢測出哪個工件有缺陷,并且分類缺陷的種類??梢钥吹饺毕菔遣恢挂环N。
二. 代碼步驟
1.讀取圖像,轉(zhuǎn)為灰度圖并二值化
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);
3.遍歷輪廓,對工件圈進行統(tǒng)計,防止重復標記
原理是計算圖像矩,可以確定圖像的灰度中心,根據(jù)每個時刻每個工件的中心位置的變換,可以判斷畫面里是否出現(xiàn)新的工件。同時,也要記得更新每個時刻每個工件的位置。具體代碼實現(xiàn)可以參考完整工程文件。這里貼出部分:
for (size_t cnt = 0; cnt < contours.size(); cnt++)
{
double area = contourArea(contours[cnt]); //求輪廓面積(大約的)
if (area > 18000 & area < 28000) //把工件圈出來
{
mu[cnt] = moments(contours[cnt], false); //計算圖像矩,表示工件的位置
//計算圖像質(zhì)心位置
double cx = mu[cnt].m10 / mu[cnt].m00;
double cy = mu[cnt].m01 / mu[cnt].m00;
boundRect[cnt] = boundingRect(Mat(contours[cnt])); //計算外接矩形
new_object = true;
//通過質(zhì)心位置判斷視頻出現(xiàn)的工件是否是最新的
if (cx > 100) //工件要全部出現(xiàn)
{
if (products.size() > 0) //判斷出現(xiàn)的工件是不是新的
{
for (size_t i = 0; i < products.size(); i++)
{
//存在一個
if (fabs(cx - products[i].getX()) <= 35 && fabs(cy - products[i].getY()) <= 35)
{
new_object = false;
//更新位置參數(shù)
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, cy, boundRect[cnt].x, boundRect[cnt].y, boundRect[cnt].width, boundRect[cnt].height);
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);
}
}
效果是這樣:
4.遍歷輪廓,把工件圈出來,順便保存調(diào)試,如下圖。圈出來的原理也不難,其實就是通過函數(shù)
boundRect[cnt] = boundingRect(Mat(contours[cnt]));
計算外接矩形,就可以獲得矩形的左上角和右下角坐標,就可以畫了。效果如下:
5.對每個框進行缺陷提取,原理依然是輪廓檢測加面積判斷。效果如下:
6.缺陷類型判斷,這里利用直方圖統(tǒng)計。即統(tǒng)計0-255中每個像素的個數(shù),根據(jù)個數(shù),轉(zhuǎn)為百分比,接著我們設(shè)定一個閾值,就可以判斷出缺陷類型。部分代碼:
//------------------------直方圖計算
Mat hist;
//設(shè)定像素取值范圍
int histSize = 256;
float range[] = {0, 256};
const float *histRanges = {range};
// hist索引為像素,值為像素點的個數(shù)
calcHist(&resul, 1, 0, Mat(), hist, 1, &histSize, &histRanges, true, false);
//-------------------------判斷缺陷
float sum = 0;
for (int i = 0; i < 256; i++)
{
float bin_val = hist.at<float>(i); //遍歷hist元素(注意hist中是float類型)
sum = sum + bin_val; //計算總的個數(shù)
}
// std::cout << "sum:"
// << sum << "\n";
//計算各個像素點的個數(shù)百分比
for (int i = 0; i < 256; i++)
{
if (hist.at<float>(i) > 0) //像素點個數(shù)大于0的時候
{
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++) //比較灰的
{
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++) //比較黑的
{
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 << "此處缺陷劃痕"
<< "\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 << "此處缺陷污漬"
<< "\n";
}
到此就可以完成啦!!!
三. 最終效果:
可以看到,會在終端打印相關(guān)消息
C++代碼純自己寫,有多文件,花了一些時間總結(jié),大家可以私信我拿代碼
另外,也準備了python代碼,需要的也可以私信我。
因為花費不少時間,所以希望大家給點報酬支持一下,繼續(xù)加油進入下一個實戰(zhàn)項目分享。
------------------------------------補充內(nèi)容---------------------------------
由于很多小伙伴下載代碼之后不知道怎么使用這代碼,今天就補充一下。首先,我們需要安裝opencv與dlib,參考下我的另外一篇文章:
ubuntu20+dlib19.22+0pencv4.5.0的機器視覺算法之路(一).
1.刪除buiild文件夾里面的所有文件
2.路徑打開到build, 執(zhí)行
cmake ..
3.接著
make
4.執(zhí)行文章來源:http://www.zghlxwxcb.cn/news/detail-443658.html
./result
搞定,完結(jié),歡迎大家來學習,當作自己的一個項目,或者可以進一步去擴展成其他東西,懂的都懂。文章來源地址http://www.zghlxwxcb.cn/news/detail-443658.html
到了這里,關(guān)于工業(yè)缺陷檢測項目實戰(zhàn)(一)——基于opencv的工件缺陷檢測C++和python實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!