opencv2-6 图像分割MeanShift
来源:互联网 发布:adobe家族软件 编辑:程序博客网 时间:2024/06/05 17:19
// 描述:包含程序所使用的头文件和命名空间
//------------------------------------------------------------------------------------------------
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
//--------------------------------------【help( )函数】--------------------------------------
// 描述:输出一些帮助信息
//----------------------------------------------------------------------------------------------
static void help()
{
cout << "\n\t此程序演示了OpenCV中MeanShift图像分割的使用。\n"
<< "\n\t程序运行后我们可以通过3个滑动条调节分割效果。调节滑动条后可能会有些许卡顿,请耐心等待\n"
<< "\n\t3个滑动条代表的参数分别为空间窗的半径 (spatialRad)、色彩窗的半径(colorRad)、最大图像金字塔级别(maxPyrLevel)\n"
<< endl;
}
//This colors the segmentations
static void floodFillPostprocess( Mat& img, const Scalar& colorDiff=Scalar::all(1) )
{
CV_Assert( !img.empty() );
RNG rng = theRNG();
Mat mask( img.rows+2, img.cols+2, CV_8UC1, Scalar::all(0) );
for( int y = 0; y < img.rows; y++ )
{
for( int x = 0; x < img.cols; x++ )
{
if( mask.at<uchar>(y+1, x+1) == 0 )
{
Scalar newVal( rng(256), rng(256), rng(256) );
floodFill( img, mask, Point(x,y), newVal, 0, colorDiff, colorDiff );
}
}
}
}
string winName = "meanshift";
int spatialRad, colorRad, maxPyrLevel;
Mat img, res;
static void meanShiftSegmentation( int, void* )
{
cout << "spatialRad=" << spatialRad << "; "
<< "colorRad=" << colorRad << "; "
<< "maxPyrLevel=" << maxPyrLevel << endl;
pyrMeanShiftFiltering( img, res, spatialRad, colorRad, maxPyrLevel );
floodFillPostprocess( res, Scalar::all(2) );
imshow( winName, res );
}
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main(int argc, char** argv)
{
help();
img = imread( "1.jpg" );
if( img.empty() )
return -1;
imshow("原始图",img);
spatialRad = 10;
colorRad = 10;
maxPyrLevel = 1;
namedWindow( winName, WINDOW_AUTOSIZE );
createTrackbar( "spatialRad", winName, &spatialRad, 80, meanShiftSegmentation );
createTrackbar( "colorRad", winName, &colorRad, 60, meanShiftSegmentation );
createTrackbar( "maxPyrLevel", winName, &maxPyrLevel, 5, meanShiftSegmentation );
meanShiftSegmentation(0, 0);
waitKey();
return 0;
}
程序说明:
1)CV_Assert( !img.empty() ); 检查出错警告语句。括号内是检测的内容,!img.empty() 的意思是:如果img图像为空,则返回0,否则返回1。
原型是宏定义:#define CV_Assert( expr ) if((expr)) ; else cv::error( cv::Exception(CV_StsAssert, #expr, "", __FILE__, __LINE__) )
如果条件expr为真,则不用执行什么操作,如果为假,则执行出错函数error()。error()函数调用Exception基类的对象。
而error()的原型是:CV_EXPORTS void error( const Exception& exc );这是出错提示函数,里面的参数是Exception对象的常引用。我们来看exception类。
Exception(异常处理机制),早期的C语言的异常处理机制,通常是人为的对返回结果加一些标志来进行判定。C语言的异常处理机制全是人为的定义,这样就会造成业务逻辑的主线受到异常处理的牵制,或者说是难免会将注意力转移,并且造成业务逻辑与异常处理之间有很大程度上的缠绕。
为什么要自定义自己的Exception ,Java Exception机制与传统的C语言的异常处理机制有什么不同,这种Exception机制的意义在什么地方?接下来咱就来和你一起探讨Exception 的优缺点。
早期的C语言的异常处理机制,通常是我们人为的对返回结果加一些标志来进行判定,比如发生错误返回什么标志,正常情况下我们又是返回什么标记,而这些都不是语言本身所赋予我们的,而对于C语言这种机制又有什么问题哩?为什么新一代的语言 Java Ruby C# 等都用Exception机制而不是维持C语言的老样子?这些都是我们需要思考的问题。
C语言的异常处理机制全是我们人为的定义,这样就会造成业务逻辑的主线受到异常处理的牵制,或者说是我们难免会将注意力转移,并且造成业务逻辑与异常处理之间有很大程度上的缠绕。
中止模型
假设错误非常严重,已至你无法在回到错误发生的地方,也就是说,这段程序经过判断认为,他已经没有办法挽回,于是就抛出异常,希望这个异常不要在回来,这也是Java 当前所采用的模式。
继续模型
这种模型的主旨是恢复当前的运行环境,然后希望能够重新回到错误的发生地,并希望第二次的尝试能够获得成功,这种模型通常为操作系统所应用。
Exception类是从基类exception派生出来的派生类。
class CV_EXPORTS Exception : public std::exception
{
public:
/*!Default constructor*/
Exception();
/*!
Full constructor. Normally the constuctor is not called explicitly.
Instead, the macros CV_Error(), CV_Error_() and CV_Assert()are used.
*/
Exception(int _code, const string& _err, const string& _func, const string& _file, int _line);
virtual ~Exception() throw();
/*!\return the error description and the context as a text string.*/
virtual const char *what() const throw();
void formatMessage();
string msg; ///< the formatted error message
int code; ///< error code @see CVStatus
string err; ///< error description
string func; ///< function name. Available only when the compiler supports __func__ macro
string file; ///< source file name where the error has occured
int line; ///< line number in the source file where the error has occured
};
class _CRTIMP_PURE exception
{ // base of all library exceptions
public:
_EXCEPTION_INLINE __CLR_OR_THIS_CALL exception();
_EXCEPTION_INLINE explicit __CLR_OR_THIS_CALL exception(const char * const &);
_EXCEPTION_INLINE __CLR_OR_THIS_CALL exception(const char * const &, int);
_EXCEPTION_INLINE __CLR_OR_THIS_CALL exception(const exception&);
_EXCEPTION_INLINE exception& __CLR_OR_THIS_CALL operator=(const exception&);
_EXCEPTION_INLINE virtual __CLR_OR_THIS_CALL ~exception();
_EXCEPTION_INLINE virtual const char * __CLR_OR_THIS_CALL what() const;
private:
_EXCEPTION_INLINE void __CLR_OR_THIS_CALL _Copy_str(const char *);
_EXCEPTION_INLINE void __CLR_OR_THIS_CALL _Tidy();
const char * _Mywhat;
bool _Mydofree;
};
2)mask.at<uchar>(y+1, x+1) == 0。运用at方式来操作像素元素,详细关于at函数原型如下:
template<typename _Tp> inline _Tp& Mat::at(Point pt)
{
CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
(unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
}
关键来看最后一句,return ((_Tp*)(data + step.p[0]*pt.y))[pt.x]。data是图像数据的首地址。data+的是地址的偏移量,step是步长,即是行与行像素之间的间距;而step.p[0]是一行像素元素的首地址。step.p[0]*pt.y则是每一行像素元素的首地址。括号外面的则是用于控制列变量的pt.x,其中pt.x和pt.y是at函数的Point类型的参数。分别用于控制列和行像素。
3)
- opencv2-6 图像分割MeanShift
- meanshift 图像分割
- meanshift图像分割示例
- opencv中的meanshift图像分割
- OpenCV meanshift 图像分割代码
- MeanShift用于彩色图像分割(OpenCV)
- 学习OpenCV2——MeanShift之图形分割
- 学习OpenCV2(四)——MeanShift之图形分割
- opencv2-4 图像分割grabCut
- 【图像算法】彩色图像分割专题八:基于MeanShift的彩色分割
- 图像分割学习笔记_1(opencv自带meanshift分割例子)
- 图像分割学习笔记_1(opencv自带meanshift分割例子)
- OpenCV之meanshift分割详解
- OpenCV2应用Meanshift查找相似物体
- OpenCV2学习笔记(四):两种图像分割方法比较
- OpenCV2 使用分水岭算法对图像分割的个人理解 cv::watershed()
- OpenCV2编程手册笔记之 5.5分水岭算法对图像进行分割
- 图像分割
- 顺序表来实现函数:删除最小值并返回删除元素,空出位置用尾部元素来填补,删除与给定值相同的所有的元素,删除给定值s,t(s<t)之间的元素
- 二层交换机、三层交换机和路由器的原理及区别
- UVALive 7008
- 给线程处理函数传结构体参数
- 操作MySQL数据库
- opencv2-6 图像分割MeanShift
- X-Space系列进阶教程七之703N 740N 710N 720N 串口辅助刷机,救砖(转载)
- 使用eclipse custom debug keystore,免去不断打包签名的麻烦
- UIScrollView
- Java核心技术第5章(2)
- 小小君的C语言第一课
- 交换机 路由器 HUB区别
- C实战:项目构建Make,Automake,CMake
- 自学QT之任务栏预览视图按钮