opencv2—(6)基于类的图像处理程序设计
2017-01-11 21:41
507 查看
传统的编程思路都是面向过程的,C++则是面向对象的编程,那么我们设计程序时应该充分使用C++封装的思想,把图像处理抽象成类。这样便于代码的维护和移植。
本篇的例子是构建一个简单算法,鉴别出图像中含有给定颜色的所有像素。该算法输入的是图像及颜色,并返回表示含有指定颜色的像素的二值图像。该算法还需要指定另一个参数,即对颜色偏差的容忍度。
但由于RGB颜色空间计算颜色之间的距离并不是衡量颜色相似度最好的方法,事实上,RGB并不是一个感知上均匀分布的色彩空间。为了解决这个问题,人们提出了感知上均匀分布的色彩空间,CIEL*a*b就是这样一个颜色空间。opencv函数cv::cvtColor可以轻易的在不同颜色空间进行转换。
下面贴代码:
ColorDetector.h
#pragma
once
[align=left]#include<opencv2\opencv.hpp>[/align]
[align=left]#include<iostream>[/align]
class
ColorDetector
[align=left]{[/align]
[align=left]private:[/align]
cv::Mat
m_converted;//转换颜色空间的图片
int
m_threshod;//容忍度偏差
cv::Vec3b
m_model;//要查找的颜色
[align=left]public:[/align]
cv::Mat
m_result;//最终得到的二值图像
[align=left] ColorDetector();[/align]
[align=left] ~ColorDetector();[/align]
void
setModel(cv::Vec3b
&target);//设置要查找的颜色
[align=left] [/align]
void
setModel(uchar
red,
uchar
green,
uchar
blue);//设置查找颜色的接口,这种颜色值设置在RGB通道上
[align=left] [/align]
void
setModel2(uchar
red,
uchar
green,
uchar
blue);//设置查找颜色的接口,这种颜色值转换到LAB颜色空间上
[align=left] [/align]
void
setThreshold(int
distance);//设置容忍度的接口
[align=left] [/align]
int
getDistance(cv::Vec3b
&pixls);//解算图像像素点与要查找的颜色的距离
[align=left] [/align]
cv::Mat
process(const
cv::Mat
&image);
cv::Mat
process2(const
cv::Mat
&image);
[align=left]};[/align]
ColorDetector.cpp
#include
"ColorDetector.h"
[align=left]//构造函数,给成员变量初始化,容忍度偏差设为100,查找的三通道颜色默认设为0[/align]
[align=left]ColorDetector::ColorDetector():m_threshod(100)[/align]
[align=left]{[/align]
m_model[0]
= m_model[1]
= m_model[2]
= 0;
[align=left]}[/align]
[align=left]ColorDetector::~ColorDetector()[/align]
[align=left]{[/align]
[align=left]}[/align]
void
ColorDetector::setModel(cv::Vec3b
&
target)
[align=left]{[/align]
m_model
=
target;//cv::Vec3b类型,三通道
[align=left]}[/align]
void
ColorDetector::setModel(uchar
red,
uchar
green,
uchar
blue)
[align=left]{[/align]
m_model[0]
=
blue;
m_model[1]
=
green;
m_model[2]
=
red;
[align=left]}[/align]
void
ColorDetector::setModel2(uchar
red,
uchar
green,
uchar
blue)
[align=left]{[/align]
cv::Mat
tmp(1, 1,
CV_8UC3);//定义一个三通道的像素点
tmp.at<cv::Vec3b>(0,
0)[0]
=
blue;
tmp.at<cv::Vec3b>(0,
0)[1]
=
green;
tmp.at<cv::Vec3b>(0,
0)[2]
=
red;
cv::cvtColor(tmp, tmp,
CV_BGR2Lab);//颜色空间转换,把RGB——>Lab
m_model
=
tmp.at<cv::Vec3b>(0,
0);
[align=left]}[/align]
void
ColorDetector::setThreshold(int
distance)
[align=left]{[/align]
m_threshod =
distance;//设置容忍度
[align=left]}[/align]
[align=left]//这里的距离公式采用1范数[/align]
int
ColorDetector::getDistance(cv::Vec3b
&
pixls)
[align=left]{[/align]
return
abs(pixls[0]
- m_model[0])
+ abs(pixls[1]
- m_model[1])
+ abs(pixls[2]
- m_model[2]);
[align=left]}[/align]
cv::Mat
ColorDetector::process(const
cv::Mat
&
image)
[align=left]{[/align]
m_result.create(image.size(),
CV_8U);
cv::Mat_<cv::Vec3b>::const_iterator
it =
image.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::const_iterator
itend =
image.end<cv::Vec3b>();
cv::Mat_<uchar>::iterator
out = m_result.begin<uchar>();
while
(it
!=
itend)
[align=left] {[/align]
[align=left] //循环遍历,把查找到的颜色转换为二值图像,这里按照RGB空间的颜色距离解算[/align]
if
(getDistance(*it)
< m_threshod)
*out
= 255;
[align=left] else[/align]
*out
= 0;
[align=left] ++it;[/align]
[align=left] ++out;[/align]
[align=left] }[/align]
return
m_result;
[align=left]}[/align]
cv::Mat
ColorDetector::process2(const
cv::Mat
&
image)
[align=left]{[/align]
m_result.create(image.size(),
CV_8U);
m_converted.create(image.size(),
image.type());
[align=left] //把输入图像从RGB颜色空间转换到Lab颜色空间[/align]
cv::cvtColor(image,
m_converted,
CV_BGR2Lab);
cv::Mat_<cv::Vec3b>::const_iterator
it = m_converted.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::const_iterator
itend = m_converted.end<cv::Vec3b>();
cv::Mat_<uchar>::iterator
out = m_result.begin<uchar>();
while
(it
!=
itend)
[align=left] {[/align]
if
(getDistance(*it)
< m_threshod)
*out
= 255;
[align=left] else[/align]
*out
= 0;
[align=left] ++it;[/align]
[align=left] ++out;[/align]
[align=left] }[/align]
return
m_result;
[align=left]}[/align]
[align=left]
[/align]
main.cpp
[align=left]#include"ColorDetector.h"[/align]
int
main()
[align=left]{[/align]
[align=left] [/align]
cv::Mat
image = cv::imread("boldt.jpg");
ColorDetector
detector;//构造类
[align=left] [/align]
[align=left] detector.setModel(130, 190, 230);//查找蓝天的颜色[/align]
[align=left] cv::namedWindow("Process");[/align]
cv::imshow("Process",
detector.process(image));
[align=left] detector.setModel2(130, 190, 230);//查找蓝天的颜色[/align]
[align=left] cv::namedWindow("Process2");[/align]
cv::imshow("Process2",
detector.process2(image));
[align=left] [/align]
[align=left] cv::waitKey(0);[/align]
return
0;
[align=left]}[/align]
运行结果:
[align=left]参考原图:[/align]
本篇的例子是构建一个简单算法,鉴别出图像中含有给定颜色的所有像素。该算法输入的是图像及颜色,并返回表示含有指定颜色的像素的二值图像。该算法还需要指定另一个参数,即对颜色偏差的容忍度。
但由于RGB颜色空间计算颜色之间的距离并不是衡量颜色相似度最好的方法,事实上,RGB并不是一个感知上均匀分布的色彩空间。为了解决这个问题,人们提出了感知上均匀分布的色彩空间,CIEL*a*b就是这样一个颜色空间。opencv函数cv::cvtColor可以轻易的在不同颜色空间进行转换。
下面贴代码:
ColorDetector.h
#pragma
once
[align=left]#include<opencv2\opencv.hpp>[/align]
[align=left]#include<iostream>[/align]
class
ColorDetector
[align=left]{[/align]
[align=left]private:[/align]
cv::Mat
m_converted;//转换颜色空间的图片
int
m_threshod;//容忍度偏差
cv::Vec3b
m_model;//要查找的颜色
[align=left]public:[/align]
cv::Mat
m_result;//最终得到的二值图像
[align=left] ColorDetector();[/align]
[align=left] ~ColorDetector();[/align]
void
setModel(cv::Vec3b
&target);//设置要查找的颜色
[align=left] [/align]
void
setModel(uchar
red,
uchar
green,
uchar
blue);//设置查找颜色的接口,这种颜色值设置在RGB通道上
[align=left] [/align]
void
setModel2(uchar
red,
uchar
green,
uchar
blue);//设置查找颜色的接口,这种颜色值转换到LAB颜色空间上
[align=left] [/align]
void
setThreshold(int
distance);//设置容忍度的接口
[align=left] [/align]
int
getDistance(cv::Vec3b
&pixls);//解算图像像素点与要查找的颜色的距离
[align=left] [/align]
cv::Mat
process(const
cv::Mat
&image);
cv::Mat
process2(const
cv::Mat
&image);
[align=left]};[/align]
ColorDetector.cpp
#include
"ColorDetector.h"
[align=left]//构造函数,给成员变量初始化,容忍度偏差设为100,查找的三通道颜色默认设为0[/align]
[align=left]ColorDetector::ColorDetector():m_threshod(100)[/align]
[align=left]{[/align]
m_model[0]
= m_model[1]
= m_model[2]
= 0;
[align=left]}[/align]
[align=left]ColorDetector::~ColorDetector()[/align]
[align=left]{[/align]
[align=left]}[/align]
void
ColorDetector::setModel(cv::Vec3b
&
target)
[align=left]{[/align]
m_model
=
target;//cv::Vec3b类型,三通道
[align=left]}[/align]
void
ColorDetector::setModel(uchar
red,
uchar
green,
uchar
blue)
[align=left]{[/align]
m_model[0]
=
blue;
m_model[1]
=
green;
m_model[2]
=
red;
[align=left]}[/align]
void
ColorDetector::setModel2(uchar
red,
uchar
green,
uchar
blue)
[align=left]{[/align]
cv::Mat
tmp(1, 1,
CV_8UC3);//定义一个三通道的像素点
tmp.at<cv::Vec3b>(0,
0)[0]
=
blue;
tmp.at<cv::Vec3b>(0,
0)[1]
=
green;
tmp.at<cv::Vec3b>(0,
0)[2]
=
red;
cv::cvtColor(tmp, tmp,
CV_BGR2Lab);//颜色空间转换,把RGB——>Lab
m_model
=
tmp.at<cv::Vec3b>(0,
0);
[align=left]}[/align]
void
ColorDetector::setThreshold(int
distance)
[align=left]{[/align]
m_threshod =
distance;//设置容忍度
[align=left]}[/align]
[align=left]//这里的距离公式采用1范数[/align]
int
ColorDetector::getDistance(cv::Vec3b
&
pixls)
[align=left]{[/align]
return
abs(pixls[0]
- m_model[0])
+ abs(pixls[1]
- m_model[1])
+ abs(pixls[2]
- m_model[2]);
[align=left]}[/align]
cv::Mat
ColorDetector::process(const
cv::Mat
&
image)
[align=left]{[/align]
m_result.create(image.size(),
CV_8U);
cv::Mat_<cv::Vec3b>::const_iterator
it =
image.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::const_iterator
itend =
image.end<cv::Vec3b>();
cv::Mat_<uchar>::iterator
out = m_result.begin<uchar>();
while
(it
!=
itend)
[align=left] {[/align]
[align=left] //循环遍历,把查找到的颜色转换为二值图像,这里按照RGB空间的颜色距离解算[/align]
if
(getDistance(*it)
< m_threshod)
*out
= 255;
[align=left] else[/align]
*out
= 0;
[align=left] ++it;[/align]
[align=left] ++out;[/align]
[align=left] }[/align]
return
m_result;
[align=left]}[/align]
cv::Mat
ColorDetector::process2(const
cv::Mat
&
image)
[align=left]{[/align]
m_result.create(image.size(),
CV_8U);
m_converted.create(image.size(),
image.type());
[align=left] //把输入图像从RGB颜色空间转换到Lab颜色空间[/align]
cv::cvtColor(image,
m_converted,
CV_BGR2Lab);
cv::Mat_<cv::Vec3b>::const_iterator
it = m_converted.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::const_iterator
itend = m_converted.end<cv::Vec3b>();
cv::Mat_<uchar>::iterator
out = m_result.begin<uchar>();
while
(it
!=
itend)
[align=left] {[/align]
if
(getDistance(*it)
< m_threshod)
*out
= 255;
[align=left] else[/align]
*out
= 0;
[align=left] ++it;[/align]
[align=left] ++out;[/align]
[align=left] }[/align]
return
m_result;
[align=left]}[/align]
[align=left]
[/align]
main.cpp
[align=left]#include"ColorDetector.h"[/align]
int
main()
[align=left]{[/align]
[align=left] [/align]
cv::Mat
image = cv::imread("boldt.jpg");
ColorDetector
detector;//构造类
[align=left] [/align]
[align=left] detector.setModel(130, 190, 230);//查找蓝天的颜色[/align]
[align=left] cv::namedWindow("Process");[/align]
cv::imshow("Process",
detector.process(image));
[align=left] detector.setModel2(130, 190, 230);//查找蓝天的颜色[/align]
[align=left] cv::namedWindow("Process2");[/align]
cv::imshow("Process2",
detector.process2(image));
[align=left] [/align]
[align=left] cv::waitKey(0);[/align]
return
0;
[align=left]}[/align]
运行结果:
[align=left]参考原图:[/align]
相关文章推荐
- 基于opencv和c++的图像处理:直方图均衡化
- 基于OPENCV的视频图像处理算法和应用
- OpenCV图像处理 空间域图像增强(图像锐化 1 基于拉普拉斯算子)
- 图像处理基础(2):自适应中值滤波器(基于OpenCV实现)
- 基于Opencv和Mfc的图像处理增强库GOCVHelper(索引)
- 基于opencv和c++的图像处理:直方图匹配
- 3_opencv2计算机视觉学习_基于类的图像处理
- 基于opencv的图像去雾处理
- 【OpenCV】【图像处理】基于轮廓的字符分割
- 基于OpenCV3.0图像处理中常见的五个滤波函数
- 基于OpenCV的CT图像处理
- linux下基于QT openCV的图像处理
- 【图像处理】基于OpenCV底层实现的图片旋转
- 基于OpenCV的火焰检测(一)——图像预处理
- 基于opencv和c++的图像处理:直方图匹配
- 【图像处理】基于OpenCV底层实现的滤波
- 基于QT+OpenCV图像处理之滤波1
- 基于MFC和OpenCV的图像处理小软件(续)
- OpenCV2计算机编程手册(二)基于类的图像处理
- 【OpenCV学习笔记 006】基于类的图像处理