main.cpp
//暗色异物处理
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
//#include <valarray>
//#include <numeric>
using namespace cv;
using namespace std;
void Dark_detection(Mat &inputimage1, Mat &inputimage2, Mat &outputimage);
void frame_sub(Mat &inputimage1, Mat &inputimage2, Mat &outputimage, int pos);
int main()
{
Mat image1 = imread("1.jpg");
Mat image2 = imread("2.jpg");
Mat outimage;
outimage.create(image1.rows, image1.cols, image1.type());
Dark_detection(image1, image2, outimage);
imshow("outimage", outimage);
}
void Dark_detection(Mat &inputimage1, Mat &inputimage2, Mat &outputimage) //暗色异物检测
{
frame_sub(inputimage1, inputimage2, outputimage, 90);
//寻找最外层轮廓
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(outputimage, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point());
Mat outputimageContours = Mat::zeros(outputimage.size(), CV_8UC1); //最小外接矩形画布
//怎样从二值化的输出图像中选出异物所在位置?
for(int i = 0; i < contours.size(); i++)
{
drawContours(outputimageContours, contours, i, Scalar(255), 1, 8, hierarchy); //绘制轮廓
RotatedRect rect = minAreaRect(contours[i]); //寻找的是异物的最小外接矩形框
Point2f p[4];
rect.points(p);
for(int j = 0; j <= 3; j++)
{
//cout<<"Points are:"<<p[j]<<endl;
line(outputimageContours, p[j], p[(j+1)%4], Scalar(255), 2); //line:第二个参数表示直线起点,第三个表示直线终点,第四个颜色,第五个是线条粗细
}
//对每个矩形框内的0像素点进行同化
}
imshow("MinAreaRect", outputimageContours);
}
void frame_sub(Mat &inputimage1, Mat &inputimage2, Mat &outputimage, int pos) //差分并二值化
{
uchar *data1 = NULL;
uchar *data2 = NULL;
uchar *data3 = NULL;
int i, j;
outputimage = inputimage1.clone();
int rowNumber = outputimage.rows;
int colNumber = outputimage.cols*outputimage.channels();
int step = outputimage.step/sizeof(uchar);
data1 = (uchar*)inputimage1.data;
data2 = (uchar*)inputimage2.data;
data3 = (uchar*)outputimage.data;
for(i = 0; i < rowNumber; i++)
{
for(j = 0; j < colNumber; j++)
{
if(fabs(data2[i*step + j] - data1[i*step + j]) > pos)
data3[i*step + j] = 255;
else
data3[i*step + j] = 0;
}
}
}
//直线表示
//定义Point2f结构体
struct Point2f
{
float x;
float y;
};
//定义直线参数结构体
struct LinePara
{
float k;
float b;
};
//获取直线参数
void getLinePara(float &x1, float &y1, float &x2, float &y2, LinePara &LP)
{
int m = 0;
m = x2 - x1;
if(0 == m)
{
LP.k = 0;
LP.b = y1 - LP.k*x1;
}
else
{
LP.k = (y2-y1)/(x2-x1);
LP.b = y1 - LP.k*x1;
}
}
//获取两点的距离,判断点两侧的p1,p2分布在p的两侧
float getLength(Point2f a, Point2f b)
{
float disx = a.x - b.x;
float disy = a.x - b.x;
float num = (disx * disx) + (disy * disy);
return sqart(num);
}
结果
失败的几个例子:
1.main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
using namespace cv;
using namespace std;
int main()
{
Mat imageSource=imread("1.jpg");
imshow("Source Image",imageSource);
Mat image;
blur(imageSource,image,Size(3,3));
threshold(image,image,0,255,CV_THRESH_OTSU);
imshow("Threshold Image",image);
//寻找最外层轮廓
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(image,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_NONE,Point());
Mat imageContours=Mat::zeros(image.size(),CV_8UC1); //最小外接矩形画布
Mat imageContours1=Mat::zeros(image.size(),CV_8UC1); //最小外结圆画布
for(int i=0;i<contours.size();i++)
{
//绘制轮廓
drawContours(imageContours,contours,i,Scalar(255),1,8,hierarchy);
drawContours(imageContours1,contours,i,Scalar(255),1,8,hierarchy);
//绘制轮廓的最小外结矩形
RotatedRect rect=minAreaRect(contours[i]);
Point2f P[4];
rect.points(P);
for(int j=0;j<=3;j++)
{
line(imageContours,P[j],P[(j+1)%4],Scalar(255),2);
}
//绘制轮廓的最小外结圆
Point2f center; float radius;
minEnclosingCircle(contours[i],center,radius);
circle(imageContours1,center,radius,Scalar(255),2);
}
imshow("MinAreaRect",imageContours);
imshow("MinAreaCircle",imageContours1);
waitKey(0);
return 0;
}
2.main.cpp
//暗色异物处理
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
//#include <valarray>
//#include <numeric>
using namespace cv;
using namespace std;
void Dark_detection(Mat &inputimage1, Mat &inputimage2, Mat &outputimage);
void frame_sub(Mat &inputimage1, Mat &inputimage2, Mat &outputimage, int pos);
int main()
{
Mat image1 = imread("1.jpg");
Mat image2 = imread("2.jpg");
Mat outimage;
outimage.create(image1.rows, image1.cols, image1.type());
Dark_detection(image1, image2, outimage);
imshow("outimage", outimage);
}
void Dark_detection(Mat &inputimage1, Mat &inputimage2, Mat &outputimage) //暗色异物检测
{
frame_sub(inputimage1, inputimage2, outputimage, 90);
//寻找最外层轮廓
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(outputimage, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point());
Mat outputimageContours = Mat::zeros(outputimage.size(), CV_8UC1); //最小外接矩形画布
//怎样从二值化的输出图像中选出异物所在位置?
for(int i = 0; i < contours.size(); i++)
{
drawContours(outputimageContours, contours, i, Scalar(255), 1, 8, hierarchy); //绘制轮廓
RotatedRect rect = minAreaRect(contours[i]); //寻找的是异物的最小外接矩形框
Point2f p[4];
rect.points(p);
for(int j = 0; j <= 3; j++)
{
//cout<<"Points are:"<<p[j]<<endl;
line(outputimageContours, p[j], p[(j+1)%4], Scalar(255), 2); //line:第二个参数表示直线起点,第三个表示直线终点,第四个颜色,第五个是线条粗细
}
//对每个矩形框内的0像素点进行同化
}
imshow("MinAreaRect", outputimageContours);
}
void frame_sub(Mat &inputimage1, Mat &inputimage2, Mat &outputimage, int pos) //差分并二值化
{
uchar *data1 = NULL;
uchar *data2 = NULL;
uchar *data3 = NULL;
int i, j;
outputimage = inputimage1.clone();
int rowNumber = outputimage.rows;
int colNumber = outputimage.cols*outputimage.channels();
int step = outputimage.step/sizeof(uchar);
data1 = (uchar*)inputimage1.data;
data2 = (uchar*)inputimage2.data;
data3 = (uchar*)outputimage.data;
for(i = 0; i < rowNumber; i++)
{
for(j = 0; j < colNumber; j++)
{
if(fabs(data2[i*step + j] - data1[i*step + j]) > pos)
data3[i*step + j] = 255;
else
data3[i*step + j] = 0;
}
}
}
//直线表示
//定义Point2f结构体
struct Point2f
{
float x;
float y;
};
//定义直线参数结构体
struct LinePara
{
float k;
float b;
};
//获取直线参数
void getLinePara(float &x1, float &y1, float &x2, float &y2, LinePara &LP)
{
int m = 0;
m = x2 - x1;
if(0 == m)
{
LP.k = 0;
LP.b = y1 - LP.k*x1;
}
else
{
LP.k = (y2-y1)/(x2-x1);
LP.b = y1 - LP.k*x1;
}
}
//获取两点的距离,判断点两侧的p1,p2分布在p的两侧
float getLength(Point2f a, Point2f b)
{
float disx = a.x - b.x;
float disy = a.x - b.x;
float num = (disx * disx) + (disy * disy);
return sqart(num);
}