本博客研究算法库中的Blob模块,语言C++
软件安装完成后,算法库的案例在C:DALSASapera ProcessingDemosVisualCpp路径中。
一定要认真参考文档SaperaProcessing.chm(在C:DALSASapera ProcessingHelp路径中)。
1、ROI使用中的注意点
CProImage一旦设定了roi,任何对处理函数的调用都将强制只对图像的这一部分进行处理。这个roi不影响内存分配,它只是存储在图像结构中的一个矩形,用来告诉处理函数在哪里处理感兴趣的数据。如果未指定roi,则将图像roi初始化为整个图像。
以640*480大小的灰度图为例,说明如下:
image.SetRoi(CProRect(160, 323, 20, 20)); // Set ROI,x、y、w、h
image.Save("image.bmp",CProImage::FileBmp); //image.bmp大小20*20
int a=image.GetWidth(); //原始尺寸。如640
int b=image.GetRoi().w; //20
image.SetRoi(CProRect()); //重置roi为原图范围
int c=image.GetRoi().w; //640
image.Save("image2.bmp",CProImage::FileBmp); //image2.bmp就是原图
2、Label与Execute
由于CProBlob类没有保存图像的函数,只有CProImage可以Save图像。而Label可以让自己选择的Blob变为CProImage,所以可以用来保存图像。
思路是先对CProImage图像进行Execute,然后筛选Blob,之后Label为CProImage图像进行保存或其他处理(如加减乘除,位与或非异或)。
Label的使用要先设置条件
CProImage proImgOut;
m_pro.Thresh(proImg,proImgOut,180,255); //二值化
m_Blob.ClearFeatures(); //blob分析前,清空
//m_blob.Label是m_blob.Execute的逆向。Label使用前,必须在Execute前设定如下一行代码来保存blob运行长度。
m_Blob.SetIntermediateResultsMode(CProBlob::IntermediateResultRuns);
//Label的参数如果是CProBlob::LabelFillHoles,必须设定如下一行代码来计算Perimeter特征。如果CProBlob::LabelGrayScale,则不需要。这两者的区别是前者是纯黑白,后者有原始灰度。
m_Blob.SetFeaturesToCompute(CProBlob::FeatureGroupPerimeter );
m_Blob.Execute(proImgOut);
m_Blob.SelectByFeature(CProBlob::FeatureArea,0,10,CProBlob::SelectRemoveOutOfRange);//面积在10以下的目标
CProImage selectedImg=proImgOut; //复制
selectedImg.Free();//Label之前,整幅图变为0当画布,接收Label的结果。只要与原图等大的CProImage都可以当画布。
m_Blob.Label(selectedImg,CProBlob::LabelFillHoles);
selectedImg.Save("selectedImg.bmp", CProImage::FileBmp);
3、blob的筛选
可以使用面积、宽度、最小外接多边形的顶点数等以及自定义的一些方法,进行blob筛选。注意筛选在Execute后。
使用CProBlob类的SelectById与SelectByFeature,前者用于具体的某一个blob,可结合自定义方法使用。
m_Blob.ClearFeatures();
m_Blob.SetFeaturesToCompute(CProBlob::FeatureGroupConvexity);//计算FeretBBoxArea,必须显示启用FeatureGroupConvexity
m_Blob.Execute(proImgOut);
for (int i=0;i<m_Blob.GetNumBlobs();++i)
{
float a=m_Blob.GetFeretBBoxArea(i)/m_Blob.GetArea(i);//最小外接矩形的面积与本身面积的比
if (a<1.6 || a>2.0) //移除满足条件的对象
{
int id=m_Blob.GetId(i); //id=i+1
m_Blob.SelectById(id,id,CProBlob::SelectRemoveInRange);
//int num2=m_Blob.GetNumBlobs();
i--; //m_Blob因为Remove会产生索引变化。
}
}
最常用的,现成的,是SelectByFeature
m_Blob.SelectByFeature(CProBlob::FeatureArea,0,10,CProBlob::SelectRemoveOutOfRange);//面积在10以下的blob
m_Blob.ClearFeatures();//先清除,再使用
m_Blob.SetFeaturesToCompute(CProBlob::FeatureGroupConvexity);//计算凸点,必须显式启用FeatureGroupConvexity
m_Blob.Execute(proImgOut);
m_Blob.SelectByFeature(CProBlob::FeatureNumConvexPoints,1,10,CProBlob::SelectRemoveOutOfRange);//最小外接多边形的顶点数在1-10之间的blob
可以使用的特征查看参考文档
4、常用函数总结
注意从上到下的逻辑关系,有的相互之间可以组合使用。
CProImage.Load 从文件中加载图像
CProImage.Save 将图像保存到文件中
CProImage.Clone 克隆(复制)图像到另一个图像。与操作符“=”等效
CProImage.Copy 从另一个图像复制数据,复制只在图像的感兴趣区域(ROI)上进行。
CProBasic.ZeroImage 生成与输入图像相同类型和大小的图像,并将所有像素值设置为0。
CProImage.Clear 用0填充图像(与上等效)
CProBasic.Fill 用一个值填充图像。可以用来制作掩膜图(纯黑白),之后进行交集、并集等。
CProImage.Roi 指定ROI区域SetRoi(CProRect& roi);可以与上一个连用,制作掩膜图。
CProBasic.AluOp 两幅CProImage的加减乘除。位操作(实现交集等)
CProBasic.UnaryOp 图与值的加减乘除
CProBasic.Thresh 阈值分割,ThreshLevelSingle让高阈值hi失效只使用lo、ThreshResultBinary意味着高于lo的像素置为255,低于的置为0。
CProImage.Merge 三通道合成彩色图
CProImage.Split 三通道拆分
CProBasic.Dilate 膨胀
CProBasic.Erode 腐蚀
CProBasic.Open 开运算
CProBasic.Close 闭运算
CProBasic.Zoom 按任意比例沿x和y轴缩放图像
CProBasic.Rotate 任意角度旋转
CProBasic.Flip 旋转,90°倍数的旋转
CProBasic.Pan 左右移动图像,负值向左、正值向右
CProBasic.Scroll 上下移动图像
CProImage.Width, Height 获取宽、高GetWidth()、GetHeight()
CProImage.GetData, SetData 获取或设置某一个坐标位置的像素值
CProBasic.CountPix 获取CProImage中非0像素个数,或者高于阈值的像素,或者在两个值之间的像素个数
CProBlob.GetNumBlobs() 获取blob的个数
CProBasic.LocalPeaks 在图像中找到局部最大值或最小值
CProBasic.Stats 平均值、标准差、最小值和最大值。