<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
首先任務背景是AOI(自動光學檢測)
最重要的目的在於:將前景和物體進行分割與分類;
場景示意圖:
需要注意,在螺母的傳送帶上,需要有前光和背光,給物體打光才能夠拍攝清晰的影象;
首先分為以下幾步:
1、噪聲抑制(預處理)
2、背景移除(分割)
3、二值化
4、連通域、輪廓查詢演演算法
降噪演演算法
先使用中值濾波對椒鹽噪聲進行過濾,再使用高斯濾波對物體邊緣進行模糊;
背景移除
首先有兩種方案可以實現背景移除,也就是減法和除法;
連通圖檢測計數
首先連通域型別分為4路連通和8路連通:
使用連通圖檢測演演算法,可以將不連通的每個物體都用不同顏色劃分出來;
如果想要多張影象展示在一個視窗中,也就是實現拼接圖片的操作,使用Python程式碼實現起來可能比較便捷,C++程式碼需要定義一個類,並且實際編寫也比較繁瑣;
class Display { private: int cols, rows, width, height; String title; vector<String> win_names; vector<Mat> images; Mat canvas; public: Display(String t, int c, int r, int flags) :title(t), cols(c), rows(r) { height = 1080; width = 1920; namedWindow(title, flags); canvas = Mat(height, width, CV_8UC3); imshow(title, canvas); } int add_window(String win_name, Mat image, bool flag = true) { win_names.push_back(win_name); images.push_back(image); if (flag) { draw(); } return win_names.size(); } // 實現刪除視窗 int delete_window(String win_name) { int index = 0; for (const auto& it : win_names) { if (it == win_name) break; index++; } win_names.erase(win_names.begin() + index); images.erase(images.begin() + index); return win_names.size(); } void draw() { canvas.setTo(Scalar(20, 20, 20)); int single_width = width / cols; int single_height = height / rows; int max_win = win_names.size() > cols * rows ? cols * rows : win_names.size(); int i = 0; auto iw = win_names.begin(); for (auto it = images.begin(); it != images.end()&&i<max_win; it++,i++,iw++) { String win_name = *iw; Mat img = *it; int x = (single_width) * (i % cols); int y = (single_height)*floor(i * 1.0 / cols); Rect mask(x, y, single_width, single_height); rectangle(canvas, mask, Scalar(255, 255, 255), 9); Mat resized_img; resize(img, resized_img, Size(single_width, single_height)); Mat sub_canvas(canvas, mask); if (resized_img.channels() == 1) { cvtColor(resized_img, resized_img, COLOR_GRAY2BGR); } resized_img.copyTo(sub_canvas); putText(sub_canvas, win_name, Point(50, 50), FONT_HERSHEY_COMPLEX, 2, Scalar(0, 0, 255), 3, LINE_AA); } imshow(title, canvas); } }; // 使用智慧指標 shared_ptr<Display> multi_window; int main(int argc, char** argv) { // 實現多視窗 String total_path = "imgpath"; String background_path = "imgpath"; Mat abc = imread(total_path, 0); multi_window = make_shared<Display>("Review for all", 3, 2, WINDOW_NORMAL); multi_window->add_window("ABC", abc); multi_window->add_window("ABCC", abc); multi_window->delete_window("ABC"); // 也支援刪除視窗 multi_window->draw(); waitKey(0); return 0; }
採用中值濾波+高斯濾波結合的降噪方法:
Mat get_background(const Mat& bg){ Mat img; medianBlur(bg,img,3); GaussianBlur(bg,img,Size(3,3),0); return img; } Mat smoothen_img(const Mat& noise_img){ Mat img; medianBlur(noise_img,img,5); GaussianBlur(img,img,Size(3,3),0); return img; }
分為兩種方式,一種為減法,一種為除法;
Mat remove_background_divide(Mat image, Mat background) { Mat tmp; Mat fg, bg; image.convertTo(fg, CV_32F); background.convertTo(bg, CV_32F); tmp = 1 - (fg / bg); tmp.convertTo(tmp, CV_8U, 255); return tmp; } Mat remove_background_minus(Mat image, Mat background) { return background - image; }
從結果圖上看,使用除法的方式能更好的保留白色部分的資訊,因此選用除法的方式;
對二值化後的影象進行連通域劃分,並且用隨機顏色繪製到Mask圖上;
void connection_check(Mat image) { Mat labels; int num = connectedComponents(image, labels); if (num <= 1) { cout << "No stuff detect!!" << endl; return; } else { cout << num << " objects detected!!" << endl; } Mat display = Mat::zeros(image.rows, image.cols, CV_8UC3); for (int i = 1; i < num; i++) { Mat mask = (labels == i); display.setTo(random_color_generator(seed), mask); } multi_window->add_window("Segment", display); }
OpenCV中也自帶了對面積區域的計算:
void connection_heavy_check(Mat image) { Mat labels, stats, centroids; int num =connectedComponentsWithStats(image, labels, stats, centroids); if (num <= 1) { cout << "No stuff detect!!" << endl; return; } else { cout << num << " objects detected!!" << endl; } Mat display = Mat::zeros(image.rows, image.cols, CV_8UC3); for (int i = 1; i < num; i++) { // 得到連通域的質心點 Point2i pt(centroids.at<double>(i, 0), centroids.at<double>(i, 1)); // 列印標籤和連通域座標和麵積 cout << "Stuff #" << i << ", Position: " << pt << " ,Area: " << stats.at<int>(i, CC_STAT_AREA) << endl; Mat mask = (labels == i); display.setTo(random_color_generator(seed), mask); stringstream ss; ss << stats.at<int>(i, CC_STAT_AREA); putText(display, ss.str(), pt, FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 255, 255), 2); } multi_window->add_window("Segment more", display); }
實現對物體輪廓的檢測;
void get_contour(Mat image) { vector<vector<Point>> contours; findContours(image, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); Mat display = Mat::zeros(image.rows, image.cols, CV_8UC3); if (contours.size() == 0) { cout << "No contour detect!!" << endl; return; } else { cout << contours.size() << " contour detected!!" << endl; } for (int i = 0; i < contours.size(); i++) { drawContours(display, contours, i, random_color_generator(seed), 2); } multi_window->add_window("CONTOURS", display); }
從上結果圖可知,檢測到的輪廓並不包含內部輪廓,如果想檢測所有輪廓應該將findContours函數中的型別引數改為RETR_LIST即可;
本次專案中涉及的技術點如下:
並且在實際的C++程式碼中,還涉及了智慧指標等高階知識;
工業質檢專案作為視覺領域較為成熟的落地專案,其大部分都是基於深度學習的方式實現了,但如果能掌握一些OpenCV的方法,也可以在專案中起到優化效果的作用;
到此這篇關於C++ OpenCV實戰之零部件的自動光學檢測的文章就介紹到這了,更多相關C++ OpenCV光學檢測內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45