您的位置:首页 > 移动开发 > Objective-C

OpenCV学习Object Segmentation

2016-06-13 16:07 465 查看
这里介绍一种物体分割和检测的一种方法。完成该功能包括了如下步骤:

1.去噪;

2.去除背景或光线;

3.二值化;

4.联通域或提取轮廓进行物体分割。



#include "opencv2/core.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
#include <stdio.h>

using namespace cv;
using namespace std;

string imgFile = "C:/Users/dell/Desktop/ni.jpg";

Scalar randomColor(RNG& rng);
Mat removeLight(Mat img, Mat pattern, int method);
Mat calculateLightPattern(Mat img);
void ConnectedComponents(Mat img);
void ConnectedComponentsStats(Mat img);
void FindContoursBasic(Mat img);

int main(int argc, const char** argv)
{
Mat img = imread(imgFile, 0);
if (img.data == NULL)
{
cout << "Error loading image" << imgFile <<endl;
return 0;
}

//去噪Noise removal
medianBlur(img, img, 3);

//计算光图像或背景
Mat pattern = calculateLightPattern(img);
imshow("pattern",pattern);

//去除背景Removing the background using the light pattern for segmentation
Mat removedPattern0 = removeLight(img, pattern, 0);
Mat removedPattern1 = removeLight(img, pattern, 1);

// 全局二值化The thresholding operation
int th = 30;//阈值
threshold(removedPattern0, removedPattern0, th, 255, CV_THRESH_BINARY);
imshow("二值化",removedPattern0);

//分割图像Segmenting our input image
//ConnectedComponentsStats(removedPattern0);
//ConnectedComponentsStats(removedPattern1);
FindContoursBasic(removedPattern0);//找出物体轮廓
//ConnectedComponents(removedPattern0);

waitKey(0);
return 0;
}

//随机色
static Scalar randomColor(RNG& rng)
{
int icolor = (unsigned)rng;
return Scalar(icolor & 255, (icolor >> 8) & 255, (icolor >> 16) & 255);
}

//background removal
Mat removeLight(Mat img, Mat pattern, int method)
{
Mat aux;
// if method is normalization
if (method == 1)
{
// Require change our image to 32 float for division
Mat img32, pattern32;
img.convertTo(img32, CV_32F);
pattern.convertTo(pattern32, CV_32F);
// Divide the image by the pattern
aux = 1 - (img32 / pattern32);
// Scale it to convert to 8bit format
aux = aux * 255;
// Convert 8 bits format
aux.convertTo(aux, CV_8U);
}
else{
aux = pattern - img;
}
return aux;
}

//creates this light pattern or background
Mat calculateLightPattern(Mat img)
{
Mat pattern;
// Basic and effective way to calculate the light pattern from one image
blur(img, pattern, Size(img.cols / 3, img.cols / 3));
return pattern;
}

void ConnectedComponents(Mat img)
{
// Use connected components to divide our possibles parts of images
Mat labels;
int num_objects = connectedComponents(img, labels);
// Check the number of objects detected
if (num_objects < 2){
cout << "No objects detected" << endl;
return;
}
else{
cout << "Number of objects detected: " << num_objects - 1 << endl;
}
// Create output image coloring the objects
Mat output = Mat::zeros(img.rows, img.cols, CV_8UC3);
RNG rng(0xFFFFFFFF);
for (int i = 1; i<num_objects; i++){
Mat mask = labels == i;
output.setTo(randomColor(rng), mask);
}
imshow("Result", output);
}

void ConnectedComponentsStats(Mat img)
{
// Use connected components with stats
Mat labels, stats, centroids;
int threshold = 1000;//检测物体大小阈值
/*
connectedComponentsWithStats(image, labels, stats, centroids, connectivity=8, ltype=CV_32S)
返回整型的检测到的分类个数,label 0 表示背景
*/
int num_objects = connectedComponentsWithStats(img, labels, stats, centroids);
// Check the number of objects detected
if (num_objects < 2){
cout << "No objects detected" << endl;
return;
}
else{
cout << "Number of objects detected: " << num_objects - 1 << endl;
}
// Create output image coloring the objects and show area
Mat output = Mat::zeros(img.rows, img.cols, CV_8UC3);
RNG rng(0xFFFFFFFF);
for (int i = 1; i<num_objects; i++){
if (stats.at<int>(i, CC_STAT_AREA) > threshold)
{
cout << "Object " << i << " with pos: " << centroids.at<Point2d>(i)
<< " with area " << stats.at<int>(i, CC_STAT_AREA) << endl;
Mat mask = labels == i;
output.setTo(randomColor(rng), mask);
// draw text with area
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));
}
}
imshow("Result", output);
}

void FindContoursBasic(Mat img)
{
vector<vector<Point> > contours;
findContours(img, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
Mat output = Mat::zeros(img.rows, img.cols, CV_8UC3);
// Check the number of objects detected
if (contours.size() == 0){
cout << "No objects detected" << endl;
return;
}
else{
cout << "Number of objects detected: " << contours.size() << endl;
}
RNG rng(0xFFFFFFFF);
for (int i = 0; i < contours.size(); i++)
drawContours(output, contours, i, randomColor(rng));
imshow("Result", output);
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: