OpenCV学习Object Segmentation
2016-06-13 16:07
465 查看
这里介绍一种物体分割和检测的一种方法。完成该功能包括了如下步骤:
1.去噪;
2.去除背景或光线;
3.二值化;
4.联通域或提取轮廓进行物体分割。
![](http://img.blog.csdn.net/20160613161637524?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
#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);
}
![](http://img.blog.csdn.net/20160613161730493?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
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);
}
相关文章推荐
- Objective-C Runtime 运行时之六:拾遗
- Objective-C Runtime 运行时之五:协议与分类
- Objective-C Runtime 运行时之四:Method Swizzling
- Objective-C Runtime 运行时之二:成员变量与属性
- Objective-C Runtime 运行时之一:类与对象
- Object.entries()
- Object.values() (非标准)
- Object.keys()
- Object.getOwnPropertyNames()
- IOS Dev Intro - Object-C Call C C++
- JdbcTemplate 版本4以上的queryforObject和queryforList的实现
- python django form error:module' object has no attribute '_meta'
- [Effective JavaScript 笔记]第31条:使用Object.getPrototypeOf函数而不要使用__proto__属性
- js(javascript)与ios(Objective-C)相互通信交互
- objective-C之NSDate相关类(四)
- objective-C之NSDate相关类(三)
- Windows下的Objective-C集成开发环境(IDE)
- objective-C之NSDate相关类(二)
- PHP 将json的stdClass Object转成数组array 方法二
- Objective-C --- - UITableView 二 对一进行一些属性补充(梳理总结)