opencv之图像区域选择(7)

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);
}

猜你喜欢

转载自blog.csdn.net/juliarjuliar/article/details/79813253