目标分类与检测实战

以下是要处理的图片:
这里写图片描述
首先第一步运用中值滤波及膨胀腐蚀处理得到图片如下:
这里写图片描述
仔细看看已经有一些黑点木有啦,那个大黑点应该已经不影响后面进行了
下面进行去背景光的操作,第一幅图为差分法,第二幅为除法

这里写图片描述

这里写图片描述
这里我们已经看到胶棒白色部分也被去除了,没办法,白色反射所有色光嘛。所以分割前可以先将白色部分通过系列操作改成别的颜色好些,这里就不做啦。
下面进行阀值化操作得到下图:

这里写图片描述

下面要开始对阀值化操作后的图片进行连通域操作了,得到下图:
这里写图片描述

还是袋子上白色的部分在去光的时候一并去除了,导致连通域多了好多内部的。还是建议去光之前将白色转色好些,最后就是画出轮廓啦。
下面给出代码:

include<iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat calculateLightPattern(Mat img);
Mat quguang(Mat img,Mat pattern);
Mat quguangchufa(Mat img,Mat pattern);

void ConnectedComponentsStats(Mat img);
static Scalar randomColor( RNG& rng )  
{  
  int icolor = (unsigned) rng;  
  return Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 );  
}  
int main(int agrc,char**agrv)
{
    Mat srcImage=imread("1.jpg");
    medianBlur(srcImage,srcImage,3);
    Mat element=getStructuringElement(MORPH_ELLIPSE,Size(7,7));
    dilate(srcImage,srcImage,element);
    erode(srcImage,srcImage,element);
    Mat pattern;
    Mat result1,result2;
    Mat img_thr;    
    pattern=calculateLightPattern(srcImage);
    result1=quguang(srcImage,pattern);
    result2=quguangchufa(srcImage,pattern); 
    //imshow("result",result2);
    //imshow("result1",result1);
    //imshow("srcImage",srcImage);
    threshold(result1,img_thr,40,255,THRESH_BINARY); //阀值来处理
    cvtColor(img_thr,img_thr,CV_RGB2GRAY);//因为
    ConnectedComponentsStats(img_thr);
    //Mat img1;
    //img_thr.convertTo(img1,CV_8SC1);
    //imshow("img_",img_thr);
    //ConnectedComponents(img1);

    waitKey(0);


}
Mat calculateLightPattern(Mat img)
{
    Mat pattern;
    blur(img,pattern,Size(img.cols/2,img.rows/2));//将原图大核模糊可近似作为光图近似值
    return pattern;
}
Mat quguang(Mat img,Mat pattern)
{
    Mat result;
    result=pattern-img;
    return result;

}
Mat quguangchufa(Mat img,Mat pattern)
{
    Mat img32,pattern32;
    img.convertTo(img32,CV_32F);
    pattern.convertTo(pattern32,CV_32F);
    Mat result;
    result=1-(img32/pattern32);
    result=result*255;
        result.convertTo(result,CV_8UC1);
    return result;  
}

void ConnectedComponentsStats(Mat img)
{
    //连通区域统计信息的三个量
    Mat labels,stats,centroids;
    int num_objects=connectedComponentsWithStats(img,labels,stats,centroids);
    //检查检测到连通域的数目
    if(num_objects<2)//1的时候应该是只有背景(个人理解)
    {
        cout<<"No object detected"<<endl;
        return;
    }
    else
    {
        cout<<"Number of objects detected:"<<num_objects-1<<endl;
    }
    Mat output=Mat::zeros(img.rows,img.cols,CV_8UC3);
    RNG rng(0xFFFFFFFF);//RNG为随机数生成器类
    for(int i=1;i<num_objects;i++)
    {
        cout<<"Object"<<i<<"with pos:"<<centroids.at<Point2d>(i)<<"with area"<<stats.at<int>(i,CC_STAT_AREA)<<endl;//A
        Mat mask=(labels==i);
        output.setTo(randomColor(rng),mask);
        //使用区域绘制文本
        stringstream ss;//添加统计区域信息
        ss<<"area:"<<stats.at<int>(i,CC_STAT_AREA);
        putText(output,ss.str(),centroids.at<Point2d>(i),FONT_HERSHEY_SIMPLEX,0.4,Scalar(255,255,255));
        //在output上描述信息(这里利用了putText函数)
    }
    imshow("result",output);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值