如何解决检测瓶坯上的缺陷
我正在做一个项目,以检测瓶坯上的缺陷。原则上,我已经准备好一切,但是我的算法对噪声和其他失真的抵抗力很差,这使它的有效性受到怀疑。你能告诉我如何改善它吗?预先感谢您的帮助 :) 附言我用C ++编写,但是我很了解Python代码,因此您可以使用任何适合您的语言。
#include "widget.h"
using namespace cv;
using namespace std;
Point cntr;
Mat main_part,fg,bg,preform,bin,M,rotated,ROI;
double getOrientation(const vector<Point> &pts)
{
//Construct a buffer used by the pca analysis
int sz = static_cast<int>(pts.size());
Mat data_pts = Mat(sz,2,CV_64F);
for (int i = 0; i < data_pts.rows; i++)
{
data_pts.at<double>(i,0) = pts[i].x;
data_pts.at<double>(i,1) = pts[i].y;
}
//Perform PCA analysis
PCA pca_analysis(data_pts,Mat(),PCA::DATA_AS_ROW);
//Store the center of the object
cntr = Point(static_cast<int>(pca_analysis.mean.at<double>(0,0)),static_cast<int>(pca_analysis.mean.at<double>(0,1)));
//Store the eigenvalues and eigenvectors
vector<Point2d> eigen_vecs(2);
vector<double> eigen_val(2);
for (int i = 0; i < 2; i++)
{
eigen_vecs[i] = Point2d(pca_analysis.eigenvectors.at<double>(i,0),pca_analysis.eigenvectors.at<double>(i,1));
eigen_val[i] = pca_analysis.eigenvalues.at<double>(i);
}
double angle = atan2(eigen_vecs[0].y,eigen_vecs[0].x); // orientation in radians
return angle;
}
// Using for find preform
int max_contour_area(vector<vector<Point>> &v) {
int max_area = 0;
for(size_t i = 0; i < v.size(); i++) {
if(v[max_area].size() < v[i].size())
max_area = (int)i;
}
return max_area;
}
int main()
{
fg = imread("C:\\Users\\Roman\\Pictures\\pf6.bmp",IMREAD_GRAYSCALE),bg = imread("C:\\Users\\Roman\\Pictures\\background.bmp",IMREAD_GRAYSCALE);
vector<vector<Point>> contours,correct_contours;
vector<Vec4i> hierarchy;
resize(fg,Size(),0.3,INTER_AREA);
resize(bg,INTER_AREA);
absdiff(fg,preform);
threshold(preform,10,255,THRESH_BINARY);
findContours(bin,contours,hierarchy,RETR_LIST,CHAIN_APPROX_NONE);
int max_area = max_contour_area(contours);
RotatedRect rBox = minAreaRect(contours[max_area]);
double angle_pca = getOrientation(contours[max_area]) * (180 / CV_PI);
if(rBox.size.width < rBox.size.height) swap(rBox.size.height,rBox.size.width);
M = getRotationMatrix2D(cntr,angle_pca,1.0);
// perform the affine transformation
warpAffine(fg,fg.size(),INTER_CUBIC,BORDER_DEFAULT);
// crop the resulting image
getRectSubPix(rotated,rBox.size,cntr,ROI);
if(ROI.cols < ROI.rows)
rotate(ROI,ROI,ROTATE_90_CLOCKWISE);
threshold(ROI,250,THRESH_BINARY_INV);
findContours(bin,THRESH_BINARY_INV);
max_area = max_contour_area(contours);
Moments mnt = moments(contours[max_area]);
Point center_mass(mnt.m10/mnt.m00,mnt.m01/mnt.m00);
Point p1(contours[max_area][0].x,p2(contours[max_area][0].x,ROI.rows-1);
// Using for find rectangle into preform
for(size_t i = 0; i < contours[max_area].size(); i++) {
if(contours[max_area][i].y == 0)
p1.x = p1.x < contours[max_area][i].x ? contours[max_area][i].x : p1.x;
if(contours[max_area][i].y == ROI.rows-1)
p2.x = p2.x < contours[max_area][i].x ? contours[max_area][i].x : p2.x;
}
if((p1.x & p2.x) > ROI.cols/2) {
p1.x = ROI.cols * 0.79;
p2.x = ROI.cols * 0.05;
}
else {
p1.x = ROI.cols * 0.17;
p2.x = ROI.cols * 0.91;
}
p1.y += ROI.rows * 0.2;
p2.y -= ROI.rows * 0.2;
Rect rect_main(p1,p2);
main_part = ROI(rect_main);
adaptiveThreshold(main_part,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY_INV,21,3);
findContours(bin,CHAIN_APPROX_NONE);
// deleting too large or too small contours
for(uint i = (uint)contours.size()-1; i != 0; --i) {
double area = contourArea(contours[i]);
if ((area >= 30) && (area <= 70))
correct_contours.push_back(contours[i]);
}
Mat defect;
main_part.convertTo(main_part,COLOR_GRAY2RGB);
ROI.convertTo(ROI,COLOR_GRAY2RGB);
// Drawing contours
vector<vector<Point>> contours_poly( correct_contours.size() );
for( size_t i = 0; i < correct_contours.size(); i++ )
approxPolyDP( correct_contours[i],contours_poly[i],1,true );
for( size_t i = 0; i< correct_contours.size(); i++ )
drawContours( main_part,correct_contours,(int)i,Scalar(255,255) );
imshow("ROI",ROI);
imshow("main",main_part);
if(waitKey() == 27) waitKey(0);
return EXIT_SUCCESS;
}
源图像: background pf1.bmp
程序结果: preform central part threshold preform result
所以,that`s我想要得到的东西
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。