一.漫水填充算法

该算法通过一个指定的种子点,来分析整张图片上的像素,并设置像素差异阈值,在阈值类的点,最后变成相同的颜色.该方法通过上下限和连通方式来达到不同的连通效果.

该方法常用与标记和分离图像的一部分,以便于对其做进一步的分析和处理,填充的结果总是连通的区域.

API:void floodFill(源图像,掩码,Point 种子点,scaral 染色值,Rect* 重绘区域的最小边界矩形区域,scaral 与种子点颜色的负差最大值,scaral 与种子点颜色的正差最大值,int 操作方式);

注:1掩码的大小和源图像相同,掩码中不为0的区域,对应的原图中坐标的像素,在处理的时候将被忽略.

2.最小矩形是一个可选参数,默认为0

3.操作方式的第八位为4,则连通时只会向水平垂直方向蔓延,为8,还包括对角线蔓延,高八位为FLOOD_FIXED_RANGE时,上下限是和种子点颜色相比,否则,是当前像素和相邻像素差

实际使用代码如下

Mat srcImage;
Mat dstImage;
Point mousePoint;
const int g_newValueMax = ;
int g_newValue;
const int g_lodiffMax = ;
int g_lodiffValue;
const int g_updiffMax = ;
int g_updiffValue; void onMouseEvent(int eventID,int x,int y,int flag,void* userData);
void onTrackBarNewValue(int pos,void* userData);
void onTrackBarLoDiffValue(int pos,void* userData);
void onTrackBarUpDiffValue(int pos,void* userData); int main(void)
{
srcImage = imread("F:\\opencv\\OpenCVImage\\floodFill.jpg");
namedWindow("floodfill image");
namedWindow("src image"); mousePoint = Point(-,-);
g_newValue = ;
g_lodiffValue = ;
g_updiffValue = ;
setMouseCallback("src image", onMouseEvent);
createTrackbar("new value", "src image", &g_newValue, g_newValueMax,onTrackBarNewValue);
createTrackbar("updiff value", "src image", &g_updiffValue, g_updiffMax,onTrackBarUpDiffValue);
createTrackbar("lodiff value", "src image", &g_lodiffValue, g_lodiffMax,onTrackBarLoDiffValue);
onTrackBarLoDiffValue(g_lodiffValue, ); imshow("src image", srcImage); moveWindow("src image", , );
moveWindow("floodfill image", srcImage.cols, ); waitKey();
return ;
} void onMouseEvent(int eventID,int x,int y,int flag,void* userData)
{
if(eventID == EVENT_LBUTTONDOWN)
{
mousePoint = Point(x,y);
onTrackBarNewValue(g_newValue, );
}
} void onTrackBarNewValue(int pos,void* userData)
{
if(mousePoint.x >= && mousePoint.y >=)
{
Rect rect;
Mat tempImage;
tempImage = srcImage.clone();
floodFill(srcImage, mousePoint, Scalar(g_newValue,g_newValue,g_newValue),&rect,Scalar(g_lodiffValue,g_lodiffValue,g_lodiffValue),Scalar(g_updiffValue,g_updiffValue,g_updiffValue),|FLOODFILL_FIXED_RANGE);
dstImage = srcImage.clone();
srcImage = tempImage.clone();
imshow("floodfill image", dstImage);
}
else
{
dstImage = srcImage.clone();
imshow("floodfill image", dstImage);
}
}
void onTrackBarLoDiffValue(int pos,void* userData)
{
if(mousePoint.x >= && mousePoint.y >=)
{
Rect rect;
Mat tempImage;
tempImage = srcImage.clone();
floodFill(srcImage, mousePoint, Scalar(g_newValue,g_newValue,g_newValue),&rect,Scalar(g_lodiffValue,g_lodiffValue,g_lodiffValue),Scalar(g_updiffValue,g_updiffValue,g_updiffValue),|FLOODFILL_FIXED_RANGE);
dstImage = srcImage.clone();
srcImage = tempImage.clone();
imshow("floodfill image", dstImage);
}
else
{
dstImage = srcImage.clone();
imshow("floodfill image", dstImage);
}
}
void onTrackBarUpDiffValue(int pos,void* userData)
{
if(mousePoint.x >= && mousePoint.y >=)
{
Rect rect;
Mat tempImage;
tempImage = srcImage.clone();
floodFill(srcImage, mousePoint, Scalar(g_newValue,g_newValue,g_newValue),&rect,Scalar(g_lodiffValue,g_lodiffValue,g_lodiffValue),Scalar(g_updiffValue,g_updiffValue,g_updiffValue),|FLOODFILL_FIXED_RANGE);
dstImage = srcImage.clone();
srcImage = tempImage.clone();
imshow("floodfill image", dstImage);
}
else
{
dstImage = srcImage.clone();
imshow("floodfill image", dstImage);
}
}

二.图像金字塔

图像金字塔是一种对图像进行向上采样或者向下采样的算法,所谓向上向下采样,实际上就是放大图像缩小图像.

图像金字塔分为高斯金字塔和拉普拉斯金字塔,高斯金字塔向下采样,降低分辨力,拉普拉斯金字塔配合高斯金字塔,向上还原源图像

下一层图像的面积是源图像面积的1/4,采样函数分别为pyrUp和pyrDown两个函数并不是互逆的,pyrDown是一个会丢失信息的函数.

API:void pyrUp(源图,目的图,Size 放大系数,int 边缘类型)

注:向上采样并放大图像,目的图和源图的通道,深度一致,放大系数有默认值,源图长*2 宽*2

API:void pyrDown(源图,目的图,Size 放大系数,int 边缘类型)

注:向下采样并模糊一张图片,图片尺寸有默认值 源图长/2 源图宽/2,整体是源图的四分之一.

使用例程如下

Mat srcImage;
//图像放大
Mat pyrupImage;
Mat pyrupShowImage;
const int g_pyrupMax = ;
int g_pyrupCount;
void onTrackBarPyrup(int pos,void* userData); //图像缩小
Mat pyrdownImage;
Mat pyrdownShowImage;
const int g_pyrdownMax = ;
int g_pyrdownCount;
void onTrackBarPyrdown(int pos,void* userData); int main(int argc,char* argv[])
{
srcImage = imread("F:\\opencv\\OpenCVImage\\pyr.jpg");
if(srcImage.empty())
{
return -;
}
namedWindow("src image");
namedWindow("pyrup image");
namedWindow("pyrdown image"); g_pyrupCount = ;
createTrackbar("pyrup count", "pyrup image", &g_pyrupCount, g_pyrupMax,onTrackBarPyrup,);
onTrackBarPyrup(g_pyrupCount,); g_pyrdownCount = ;
createTrackbar("pyrdown count", "pyrdown image", &g_pyrdownCount, g_pyrdownMax,onTrackBarPyrdown,);
onTrackBarPyrdown(g_pyrdownCount, ); imshow("src image", srcImage); moveWindow("src image", , );
moveWindow("pyrup image", srcImage.cols, );
moveWindow("pyrdown image", srcImage.cols*, ); waitKey();
return ;
}
//图像放大
void onTrackBarPyrup(int pos,void* userData)
{
if(pos == )
{
imshow("pyrup image", srcImage);
}
else
{
Mat tempImage;
tempImage = srcImage.clone();
for(int i = ; i < pos; i++)
{
pyrUp(tempImage, pyrupImage);
tempImage = pyrupImage.clone();
}
if(pyrupImage.cols > srcImage.cols && pyrupImage.rows > srcImage.rows)
{
//pyrupShowImage = pyrupImage(Range(0,srcImage.rows),Range(0,srcImage.cols));
imshow("pyrup image", pyrupImage);
}
else
{
imshow("pyrup image", pyrupImage);
}
}
}
//图像缩小
void onTrackBarPyrdown(int pos,void* userData)
{
if(pos == )
{
imshow("pyrdown image", srcImage);
}
else
{
Mat tempImage;
tempImage = srcImage.clone();
for(int i = ; i < pos; i++)
{
pyrDown(tempImage, pyrdownImage);
tempImage = pyrdownImage.clone();
}
if(pyrdownImage.cols > srcImage.cols && pyrdownImage.rows > srcImage.rows)
{
pyrdownShowImage = pyrdownImage(Range(,srcImage.rows),Range(,srcImage.cols));
imshow("pyrdown image", pyrdownShowImage);
}
else
{
imshow("pyrdown image", pyrdownImage);
}
}
}

三.图像大小重新调整resize

resize用于将源目标精确的转换为指定大小的目标图像,在图像放大缩小的时候很有用

API: void resize(源,目标,Size 目标尺寸,double x方向缩放系数,double y方向上缩放系数,int 差值方式)

注:x方向缩放系数默认值0,函数自动根据源图像大小和目标尺寸计算,y方向缩放系数也是一样.插值方式决定了放大缩小以后的效果,主要有如下几种插值方法 INTER_LINE 线性插值INTER_NEAREST 最近邻插值  INNER_CUBIC 4*4区域内三次样条插值INNER_AREA 区域插值INNER_LANCZOS4 8*8区域内邻域插值.

插值方式的选择对于多次resize有很大影响,例子如下

//图像重新设置大小 resize
Mat srcImage;
const int g_resizeMax = ;
int g_resizeValue = ;
Mat resizeImage;
void onTrackBarResize(int pos,void* userData); int main(int argc,char* argv[])
{
srcImage = imread("F:\\opencv\\OpenCVImage\\resize.jpg"); namedWindow("src image");
namedWindow("resize image"); g_resizeValue = srcImage.rows;
createTrackbar("size value", "resize image", &g_resizeValue, g_resizeMax,onTrackBarResize,);
onTrackBarResize(g_resizeValue, ); imshow("src image", srcImage); moveWindow("src image", , );
moveWindow("resize image", srcImage.cols, ); waitKey();
return ;
} void onTrackBarResize(int pos,void* userData)
{
if(pos == )
{
imshow("resize image", srcImage);
}
else
{
//INTER_LINEAR INTER_CUBIC INTER_AREA INTER_NEAREST
resize(srcImage, resizeImage, Size(g_resizeValue,g_resizeValue),,,INTER_NEAREST);
imshow("resize image", resizeImage);
}
}

四:图像的阈值化

图像的阈值化是指通过一些算法和决策手段,将图像中的像素编程两种指定像素的集合,例如,将灰度图转换成完全的黑白图,或者直接提出低于或者高于一定值的像素.

图像的阈值化在某些场合下,对于图像的边缘提取十分有效果.

API: void Threshold(源图,目标图,double 阈值,double 最大值,int 阈值类型)

注:1.源和目标图都必须是单通道灰度图像

2.阈值类型决定了阈值化以后,图像中将仅存在哪两种像素点

THRESH_BINARY 低于阈值为0 高于阈值为给定最大值

THRESH_BINARY_INV 低于阈值为给定最大值 高于阈值为0

THRESH_TRUNC    低于阈值,保持原来像素不变,高于阈值,为阈值

THRESH_TOZERO 低于阈值为0,高于阈值保持原来值比边

THRESH_TOZERO_INV 低于阈值保持原来值比边,高于阈值为0

API:void adaptiveThreshold(源,目的,double 最大值,int 自适应算法类型,int 阈值类型,int 自适应            算法的邻域尺寸,double 减去平均或者加权平均中的常数值).

注:该算法是自适应阈值化,自动根据邻域中一个范围的值确定某一点的确定像素阈值,源和目的都需要时单通道图像,阈值类型必须为THRESH_BINARY或者是THRESH_BINARY_INV的一种,自适应算法有两种选择,ADAPTIVE_THRESH_MEAN_C  以邻域尺寸内平均值为阈值,ADAPTIVE_THRESH_GAUSSIAN_C 邻域矩阵值与高斯窗口函数交叉相关的加权综合

使用例程如下

Mat srcImage;
Mat srcSingleImage; //正y常¡ê阈D值¦Ì化¡¥
Mat thresholdImage;
const int g_thresholdMax = ;
int g_thresholdValue;
const int g_thresholdMaxMax = ;
int g_thresholdMaxValue; void onTrackBarThresholdValue(int pos,void* userData);
void onTrackBarThresholdMax(int pos,void* userData); //自Á?适º¨º应®|阈D值¦Ì化¡¥
Mat adaptiveThresholdImage;
const int g_adaptiveThresholdMaxMax = ;
int g_adaptiveThresholdMaxValue; void onTrackBarAdaptiveThresholdMax(int pos,void* userData); int main(int argc,char* argv[])
{
srcImage = imread("F:\\opencv\\OpenCVImage\\adaptiveThreshold.png");
if(srcImage.channels() == )
{
srcSingleImage = srcImage(Range(,srcImage.rows),Range(,srcImage.cols));
}
else
{
srcSingleImage = Mat(srcImage.rows, srcImage.cols, CV_8UC1);
cvtColor(srcImage, srcSingleImage, CV_RGB2GRAY);
} namedWindow("src image"); g_thresholdValue = ;
g_thresholdMaxValue = ;
namedWindow("threshold image");
createTrackbar("threshold max", "threshold image", &g_thresholdMaxValue, g_thresholdMaxMax,onTrackBarThresholdMax,);
createTrackbar("threshold value", "threshold image", &g_thresholdValue, g_thresholdMax,onTrackBarThresholdValue,);
onTrackBarThresholdValue(g_thresholdValue, ); g_adaptiveThresholdMaxValue = ;
namedWindow("adaptiveThreshold image");
createTrackbar("adaptiveThreshold Max", "adaptiveThreshold image", &g_adaptiveThresholdMaxValue, g_adaptiveThresholdMaxMax,onTrackBarAdaptiveThresholdMax,);
onTrackBarAdaptiveThresholdMax(g_adaptiveThresholdMaxValue, ); imshow("src image", srcSingleImage); moveWindow("src image", , );
moveWindow("threshold image", srcSingleImage.cols, );
moveWindow("adaptiveThreshold image", srcSingleImage.cols*, ); waitKey();
return ;
} //正y常¡ê阈D值¦Ì化¡¥,需¨¨要°a指?定¡§阈D值¦Ì以°?及¡ã最Á?大䨮值¦Ì
void onTrackBarThresholdValue(int pos,void* userData)
{
if (g_thresholdMaxValue == )
{
imshow("threshold image", srcSingleImage);
}
else
{
threshold(srcSingleImage, thresholdImage, g_thresholdValue, (double)g_thresholdMaxValue, THRESH_BINARY);
imshow("threshold image", thresholdImage);
}
}
void onTrackBarThresholdMax(int pos,void* userData)
{
if (g_thresholdMaxValue == )
{
imshow("threshold image", srcSingleImage);
}
else
{
threshold(srcSingleImage, thresholdImage, g_thresholdValue, (double)g_thresholdMaxValue, THRESH_BINARY);
imshow("threshold image", thresholdImage);
}
} //自适应阈值化,只需要指定最大值就好了
void onTrackBarAdaptiveThresholdMax(int pos,void* userData)
{
if(g_adaptiveThresholdMaxValue == )
{
imshow("adaptiveThreshold image", srcSingleImage);
}
else
{
adaptiveThreshold(srcSingleImage, adaptiveThresholdImage, g_adaptiveThresholdMaxValue, THRESH_BINARY, ADAPTIVE_THRESH_MEAN_C, , );
imshow("adaptiveThreshold image", adaptiveThresholdImage);
}
}

OPENCV形态学算法-2的更多相关文章

  1. Opencv分水岭算法——watershed自动图像分割用法

    分水岭算法是一种图像区域分割法,在分割的过程中,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓,封闭性是分水岭算法的一个重要特 ...

  2. Win8 Metro(C#)数字图像处理--2.75灰度图像的形态学算法

    原文:Win8 Metro(C#)数字图像处理--2.75灰度图像的形态学算法 前面章节中介绍了二值图像的形态学算法,这里讲一下灰度图的形态学算法,主要是公式,代码略. 1,膨胀算法 2,腐蚀算法 3 ...

  3. OPENCV形态学操作1

    形态学操作是指基于形状的一系列图像处理操作,包括膨胀,腐蚀,二值化,开运算,闭运算,顶帽算法,黑帽算法,形态学梯度等,最基本的形态学操作就是膨胀和腐蚀. 一.膨胀 首先需要明确一个概念,膨胀和腐蚀都是 ...

  4. opencv——形态学深究(分析和应用)

    摘要: 形态学一般指生物学中研究动物和植物结构的一个分支.用数学形态学(也称图像代数)表示以形态为基础对图像进行分析的数学工具. 基本思想是用具有一定形态的结构元素去度量和提取图像中的对应形状以达到对 ...

  5. OpenCV白平衡算法之灰度世界法(消除RGB受光照影响)

    在用OpenCV对图像进行处理时,利用颜色定位是常常会接触到的方法,但RGB受光照影响比较严重,转换到HSV XYZ等空间也解决不了时, 可以用白平衡算法进行修正,使其发黄.发蓝.发红的照片更加趋于自 ...

  6. opencv分水岭算法对图像进行切割

    先看效果 说明 使用分水岭算法对图像进行切割,设置一个标记图像能达到比較好的效果,还能防止过度切割. 1.这里首先对阈值化的二值图像进行腐蚀,去掉小的白色区域,得到图像的前景区域.并对前景区域用255 ...

  7. opencv 一堆算法,图像处理等

    http://blog.csdn.net/wangzhebupt/article/category/1675453 数据挖掘十大经典实用算法及OpenCV算法 http://www.xuebuyuan ...

  8. OpenMP并行编程应用—加速OpenCV图像拼接算法

    OpenMP是一种应用于多处理器程序设计的并行编程处理方案,它提供了对于并行编程的高层抽象.仅仅须要在程序中加入简单的指令,就能够编写高效的并行程序,而不用关心详细的并行实现细节.减少了并行编程的难度 ...

  9. Opencv+Yolov3算法实现社交距离安全检测讲解和实战(Social Distance Detector)

    在我们进行交流谈话时,人与人之间总要保持一定的距离,尤其是在疫情的情况下,人与人之间更要保持一定的安全距离,今天给大家来介绍一个检测社交距离的项目,实现社交距离检测器. 社交距离(Social Dis ...

随机推荐

  1. 判断是ios还是android

    //判断是ios还是androidvar system;var ua = navigator.userAgent.toLowerCase(); if (/iphone|ipad|ipod/.test( ...

  2. HDU 1022 Train Problem I 用栈瞎搞

    题目大意:有n辆火车,按一定的顺序进站(第一个字符串顺序),问是否能按规定的顺序出站(按第二个字符串的顺序出去),如果能输出每辆火车进出站的过程. 题目思路:栈的特点是先进后出,和题意类似,还有有一种 ...

  3. 【转】ThinkPHP 页面跳转

    ThinkPHP 提供了success 与error 方法用于带提示信息的页面跳转,如添加数据后显示提示信息并跳转等.success 方法用于操作成功后的提示,error 用于操作失败后的提示,二者使 ...

  4. boost库之geometry<二>

    #include <boost/assign.hpp> #include <boost/geometry/core/point_type.hpp> #include <b ...

  5. php 生成 验证码的例子

    /** +---------------------------------------------------------- * 生成随机字符串  CuPlayer.com 酷播 +-------- ...

  6. php 后台权限例子 (mysql 数据表)

    说明   超级管理员的权限最高   可以操作所有的功能   !!!      超级管理员给特定的用户分配对应的权限 下文注解:   用户表 关联 用户组表  每个用户组对应特定的功能权限    !! ...

  7. php cookies自动登录

    <?php header('Content-type: text/html; charset=utf-8'); error_reporting(0); //自动登陆 if($_COOKIE[&q ...

  8. PullToRefreshListView上拉加载、下拉刷新

    说明:此项目使用studio完成的.需要导入library作为依赖,使用了xuitls获得网络请求.使用Pull解析了XML eclipse中的项目: //注意:此刷新功能是使用的第三方的PullTo ...

  9. 网络获取数据的Xml的Pull解析

    网络获取的XML的Pull解析 <?xml version="1.0" encoding="utf-8" ?> - <students> ...

  10. UVALive 7291 Kinfolk(最近公共祖先)

    题目中的描述就很最近公共祖先,再说其实这个题并不难,就是麻烦点(代码其实可以化简的),我写的判定比较多. 方法:求出两者的最近公共祖先lca,在求出两者到lca的距离 分析:给出a和b,如果LCA(a ...