您的位置:首页 > 运维架构

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]

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: