Opencv计算机视觉编程攻略-第三节 图像颜色处理

第三节 图像颜色处理

1.颜色比较

主要实现逐像素的颜色比较,其中注意BGR颜色空间不连续,不利于颜色提取和区分,转换到Lab空间:

cpp 复制代码
	  int getColorDistance(const cv::Vec3b& color1, const cv::Vec3b& color2) const {
	      // 方法一
		  return abs(color1[0]-color2[0])+
					abs(color1[1]-color2[1])+
					abs(color1[2]-color2[2]);
		 // 方法二
		  return static_cast<int>(cv::norm<int,3>(cv::Vec3i(color[0]-color2[0],color[1]-color2[1],color[2]-color2[2])));
		  // 方法三 直接使用函数
		  cv::Vec3b dist;
		  cv::absdiff(color,color2,dist);
		  return cv::sum(dist)[0];
	  }
	  // 使用指针遍历图像进行颜色比较
	  Mat process(const Mat &image) {
	  
	  // same size as input image, but 1-channel
	  result.create(image.size(),CV_8U);
	  // Converting to Lab color space  
	  if (useLab)
		  cv::cvtColor(image, converted, cv::COLOR_BGR2Lab);
	  // get the iterators
	  Mat_<cv::Vec3b>::const_iterator it= image.begin<Vec3b>();
	  Mat_<cv::Vec3b>::const_iterator itend= image.end<Vec3b>();
	  Mat_<uchar>::iterator itout= result.begin<uchar>();

	  // get the iterators of the converted image 
	  if (useLab) {
		  it = converted.begin<cv::Vec3b>();
		  itend = converted.end<cv::Vec3b>();
	  }
	  // 指针遍历
	  for ( ; it!= itend; ++it, ++itout) {
		  // compute distance from target color
		  if (getDistanceToTargetColor(*it)<maxDist) {
			  *itout= 255;
		  } else {
			  *itout= 0;
		  }
        // end of pixel processing ----------------
	  }
	  return result;
}

2.GrabCut分割图像

floodFill函数,支持用户选择种子点,opencv依据差异值进行快速处理,比如office中的设置透明色,就类似于该算法的实现

cpp 复制代码
	// testing floodfill
	cv::floodFill(image,            // input/ouput image
		cv::Point(100, 50),         // seed point
		cv::Scalar(255, 255, 255),  // repainted color(0,0,0)则是黑色
		(cv::Rect*)0,  // bounding rectangle of the repainted pixel set
		cv::Scalar(35, 35, 35),     // low and high difference threshold
		cv::Scalar(35, 35, 35),     // most of the time will be identical
		cv::FLOODFILL_FIXED_RANGE); // pixels are compared to seed color

	cv::namedWindow("Flood Fill result");
	result = colordetector(image);

GrabCut分割图像通过用户标记前景框,算法为2004年提出,主要是将图像依据颜色相似进行图块分割,然后再使用边缘特征进一步分割,将问题转化为连通图的合并问题,最后以四种类型作为结果输出

cpp 复制代码
	// define bounding rectangle 
	cv::Rect rectangle(50,25,210,180);
	// the models (internally used)
	cv::Mat bgModel,fgModel; 
	// segmentation result
	cv::Mat result; // segmentation (4 possible values)

	// GrabCut segmentation
	cv::grabCut(image,    // input image
		result,   // segmentation result
		rectangle,// rectangle containing foreground 
		bgModel, fgModel, // models
		5,        // number of iterations
		cv::GC_INIT_WITH_RECT); // use rectangle

	// Get the pixels marked as likely foreground GC_PR_FGD有四种不同分类结果
	cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);
	// or:
    //	result= result&1;

两种方法对比图下,GrabCut能够有效保留前景要素边缘特征

最终基于边框提取前景要素:

3.色调、饱和度以及亮度

将图像转换到连续空间Lab进行处理往往可以获得更为连续的结果,而HSV颜色表示更加符合人类视觉感知

cpp 复制代码
cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);
cv::cvtColor(hsv,newImage, cv::COLOR_HSV2BGR);
cv::cvtColor(image,brightness, cv::COLOR_Lab2BGR);

void detectHScolor(const cv::Mat& image,		// input image 
	double minHue, double maxHue,	// Hue interval 
	double minSat, double maxSat,	// saturation interval
	cv::Mat& mask) {				// output mask

	// convert into HSV space
	cv::Mat hsv;
	cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);

	// split the 3 channels into 3 images
	std::vector<cv::Mat> channels;
	cv::split(hsv, channels);
	// channels[0] is the Hue
	// channels[1] is the Saturation
	// channels[2] is the Value

	// Hue masking
	cv::Mat mask1; // below maxHue
	cv::threshold(channels[0], mask1, maxHue, 255, cv::THRESH_BINARY_INV);
	cv::Mat mask2; // over minHue
	cv::threshold(channels[0], mask2, minHue, 255, cv::THRESH_BINARY);

	cv::Mat hueMask; // hue mask
	if (minHue < maxHue)
		hueMask = mask1 & mask2;
	else // if interval crosses the zero-degree axis
		hueMask = mask1 | mask2;

	// Saturation masking
	// below maxSat
	cv::threshold(channels[1], mask1, maxSat, 255, cv::THRESH_BINARY_INV);
	// over minSat
	cv::threshold(channels[1], mask2, minSat, 255, cv::THRESH_BINARY);

	cv::Mat satMask; // saturation mask
	satMask = mask1 & mask2;

	// combined mask
	mask = hueMask&satMask;
}

诸如人体皮肤再HSV颜色域中具有显著的特征

该节相关代码已上传到个人文档,按需下载链接: 点击下载

相关推荐
2201_7549184115 分钟前
OpenCV 背景建模详解:从原理到实战
人工智能·opencv·计算机视觉
思通数据6 小时前
AI全域智能监控系统重构商业清洁管理范式——从被动响应到主动预防的监控效能革命
大数据·人工智能·目标检测·机器学习·计算机视觉·数据挖掘·ocr
jndingxin7 小时前
OpenCV CUDA模块中矩阵操作------范数(Norm)相关函数
人工智能·opencv
MUTA️8 小时前
ultalytics代码中模型接收多层输入的处理
深度学习·算法·yolo·机器学习·计算机视觉
巷9558 小时前
OpenCV光流估计:原理、实现与应用
人工智能·opencv·计算机视觉
jndingxin10 小时前
OpenCV CUDA模块中逐元素操作------数学函数
人工智能·opencv·计算机视觉
Eric.Lee202110 小时前
python opencv 将不同shape尺寸的图片制作video视频
python·opencv·音视频
白熊18813 小时前
【计算机视觉】OpenCV实战项目:基于OpenCV与face_recognition的实时人脸识别系统深度解析
人工智能·opencv·计算机视觉
闭月之泪舞13 小时前
OpenCv高阶(4.0)——案例:海报的透视变换
人工智能·opencv·计算机视觉
jndingxin13 小时前
OpenCV CUDA模块中矩阵操作-----矩阵最大最小值查找函数
人工智能·opencv