一颜色空间转换
cvtColor函数
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 )
/*dstCn为目标图像的通道数,如果为0,表示目标图像的通道数取源图像的通道数
*code颜色空间转换标识符:
*可以实现BGR,BGRA,Gray,5X5,CIE XYZ,YCrCb(YUV)
*JPEG,HSV,HLS,CIE L*a*b,CIE L*a*b,CIE L*u*v,Bayer颜色空间之间的转换
*RGB和Gray:CV_BGR2GRAY, CV_RGB2GRAY, CV_GRAY2BGR, CV_GRAY2RGB
*RGB和CIE XYZ:CV_BGR2XYZ, CV_RGB2XYZ, CV_XYZ2BGR, CV_XYZ2RGB
*RGB和HSV:CV_BGR2HSV, CV_RGB2HSV, CV_HSV2BGR, CV_HSV2RGB
*RGB和HLS:CV_BGR2HLS, CV_RGB2HLS, CV_HLS2BGR, CV_HLS2RGB
*RGB和CIE L*a*b*:CV_BGR2Lab, CV_RGB2Lab, CV_Lab2BGR, CV_Lab2RGB
*RGB和CIE L*u*v*:CV_BGR2Luv, CV_RGB2Luv, CV_Luv2BGR, CV_Luv2RGB
*Bayer和RGB:CV_BayerBG2BGR, CV_BayerGB2BGR, CV_BayerRG2BGR,
*CV_BayerGR2BGR, CV_BayerBG2RGB, CV_BayerGB2RGB,
*CV_BayerRG2RGB, CV_BayerGR2RGB
*/
二阈值化
基本思想:给定一个Mat和一个阈值,然后根据数组每个元素的值是高于还是低于阈值而进行处理
1>固定阈值操作
double threshold(InputArray src, OutputArray dst,
double thresh, double maxval, int type)
//src单通道,8-bit或者浮点型
//thresh 阈值
//maxval是否使用由type决定
type:
THRESH_BINARY:
THRESH_BINARY_INV:
THRESH_TRUNC:
THRESH_TOZERO:
THRESH_TOZERO_INV:
如图:
2>自适应阈值操作
void adaptiveThreshold(InputArray src, OutputArray dst,
double maxValue, int adaptiveMethod,
int thresholdType, int blockSize, double C)
/*src,8-bit单通道
*maxValue给像素赋满足条件的值
*adaptiveMethod,自适应阈值的算法,ADAPTIVE_THRESH_MEAN_C和
*ADAPTIVE_THRESH_GAUSSIAN_C
*thresholdType,阈值类型
*blockSiz,计算像素大小的邻域尺寸
*C减去平均或加权平均值后的常数值
*/
thresholdType:
THRESH_BINARY:
THRESH_BINARY_INV:
T(x,y)是一个单独的像素值
对于adaptiveMethod:
ADAPTIVE_THRESH_MEAN_C:
T(x,y)是blockSize×blockSize范围内像素值的和减去C后的平均值
ADAPTIVE_THRESH_GAUSSIAN_C:
T(x,y)是blockSize×blockSize范围内高斯相关的加权和减去C
应用:
//THRESH_TOZERO_INV方法,阈值200,maxval为255
cv::threshold(Image,result5,200,255,cv::THRESH_TOZERO_INV);
//THRESH_BINARY方法,ADAPTIVE_THRESH_MEAN_C取平均值
cv::adaptiveThreshold(Image,result1,255,cv::ADAPTIVE_THRESH_MEAN_C,
cv::THRESH_BINARY,7,5);
效果图:
固定阈值:
自适应阈值:
三漫水填充
用特定的颜色填充连通区域,自动选中和种子相连的区域,接着将该区域替换成制定的颜色。
int floodFill(InputOutputArray image, Point seedPoint,
Scalar newVal, Rect* rect=0,
Scalar loDiff=Scalar(), Scalar upDiff=Scalar(),
int flags=4 )
/*image,1或3通道,8-bit或fudianxing
*seedPoint,算法的起始点
*newVal,被替代像素的新值
*rect,用于圈出来,要进行floodFill操作的区域
*loDiff,当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的
*亮度或颜色之负差的最大值
*upDiff,当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的
*亮度或颜色之正差的最大值
*flags:
*低八位(0~7位)控制算法的连通性,4表示只考虑上下左右像素,8再加上对角线
*高八位(16~23位)可以为0,或者
*FLOODFILL_FIXED_RANGE,如果设定,则当前的像素值和seedPoint的像素差会
*被考虑,否则只会考虑当前像素值和邻域的像素值的差异
*FLOODFILL_MASK_ONLY,如果设定了,image图像不会改变,只会在掩码填充
*/
//rect为NULL,则应用到全图
cv::Rect rect;
//选择种子点
cv::Point p(image.cols/2,image.rows/2);
//flags默认为0
cv::floodFill(image,p,cv::Scalar(155,255,55),&rect,
cv::Scalar(8,8,8),cv::Scalar(8,8,8));
效果图:
四前景图像分离
将前景物体从背景中分离出来
void grabCut(InputArray img, InputOutputArray mask, Rect rect,
InputOutputArray bgdModel, InputOutputArray fgdModel,
int iterCount, int mode=GC_EVAL )
/*img输入图像,三通道8-bit
*mask,输入输出图像,单通道8-bit,当mode=GC_INIT_WITH_RECT时mask由函
*数初始化,否则要手动初始化,像素只可能为以下值:
*GC_BGD,代表此处肯定是背景
*GC_FGD,代表此处肯定是前景
*GC_PR_BGD,代表此处可能是背景
*GC_PR_FGD,代表此处可能是前景
*rect,在rect表明可能有前景,rect之外绝对是背景,mode=GC_INIT_WITH_RECT
*bgdModel,背景模型的临时数组,当你处理相同的图片不要修改它
*fgdModel,前景模型的临时数组,当你处理相同的图片不要修改它
*iterCount,算法迭代次数,mode==GC_INIT_WITH_MASK或mode==GC_EVAL,
*可以增加精度
*mode:
*GC_INIT_WITH_RECT,用矩阵初始化mask,然后进行迭代
*GC_INIT_WITH_MASK,利用已经初始化的mask,进行运算
*GC_EVAL,默认值,代表算法要恢复
mask,作为输出图像,前景物体的位置会被标记为,GC_FGD或者GC_PR_FGD,利用mask将物体提取(详细的代码在opencv sample grabcut.cpp),以下简单说明:
cv::Mat image=cv::imread("1.jpg",1);
//大致圈出前景物体
cv::Rect rect(10,10,image.cols-20,image.rows-20);
cv::Mat mask;
cv::Mat bgdModel,fgdModel;
//选择RECT方法,迭代一次
cv::grabCut(image,mask,rect,bgdModel,fgdModel,1,
cv::GC_INIT_WITH_RECT);
//将像素值==GC_PR_FGD,的点留下,剩下为0
cv::compare(mask,cv::Scalar(cv::GC_PR_FGD),mask,cv::CMP_EQ);
cv::Mat result;
//将mask,作为掩码拷贝
image.copyTo(result,mask);
cv::imshow("grabCut",result);
cv::waitKey();
效果图(黑色区域为背景):