当前位置: 首页 > news >正文

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

第三节 图像颜色处理

  • 1.颜色比较
  • 2.GrabCut分割图像
  • 3.色调、饱和度以及亮度

1.颜色比较

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

	  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中的设置透明色,就类似于该算法的实现

	// 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年提出,主要是将图像依据颜色相似进行图块分割,然后再使用边缘特征进一步分割,将问题转化为连通图的合并问题,最后以四种类型作为结果输出

	// 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颜色表示更加符合人类视觉感知

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颜色域中具有显著的特征
在这里插入图片描述

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

相关文章:

  • 【docker】docker-compose安装RabbitMQ
  • 08-项目中不可控的任务如何安排和验收
  • WPF(Windows Presentation Foundation)与 C# 基础知识详解
  • 【Linux知识】RPM软件包安装命令行详细说明
  • 代码随想录Day23
  • [ComfyUI] AlekPetNodes 插件详解:节点与模型管理
  • 2小样本学习(Few-Shot)之相似度
  • 000-JMeter简介
  • JVM之类的加载过程
  • 硬件基础--02_前序知识
  • 【C++】STL性能优化实战
  • 硬件基础(3):三极管(4):关于三极管的压降
  • 诡异的服务重启原因探索
  • 【AWS】使用CloudFront S3 Lambda打造丝滑低延迟Web体验
  • Java面试题及知识点Day1
  • 【构建性能分析插件设计与实现:打造前端项目的性能透视镜】
  • 初阶5 STL简介
  • 嵌入式硬件开发中如何将对应的EDA文件导入PADS方法
  • 斜线、短横、空格,三种分隔日期的优雅解析(Python | DeepSeek)
  • 模型 拆屋效应
  • “马上涨价”再到“吞下关税”,美政策让沃尔玛“输两次”
  • 北方首场高温将进入鼎盛阶段,江南华南多地需警惕降雨叠加致灾
  • 蒲慕明院士:未来数十年不是AI取代人,而是会用AI的人取代不会用的
  • 河南一县政府党组成员签订抵制违规吃喝问题承诺书,现场交给县长
  • 湖北宜化拟斥资超32亿加价回购“弃子”,布局上游煤炭业务
  • 董军同德国国防部长举行会谈