opencv2—(6)基于类的图像处理程序设计

传统的编程思路都是面向过程的,C++则是面向对象的编程,那么我们设计程序时应该充分使用C++封装的思想,把图像处理抽象成类。这样便于代码的维护和移植。
本篇的例子是构建一个简单算法,鉴别出图像中含有给定颜色的所有像素。该算法输入的是图像及颜色,并返回表示含有指定颜色的像素的二值图像。该算法还需要指定另一个参数,即对颜色偏差的容忍度。
但由于RGB颜色空间计算颜色之间的距离并不是衡量颜色相似度最好的方法,事实上,RGB并不是一个感知上均匀分布的色彩空间。为了解决这个问题,人们提出了感知上均匀分布的色彩空间,CIEL*a*b就是这样一个颜色空间。opencv函数cv::cvtColor可以轻易的在不同颜色空间进行转换。
下面贴代码:

ColorDetector.h

#pragma once
#include <opencv2\opencv.hpp>
#include <iostream>
class ColorDetector
{
private :
       cv:: Mat m_converted; //转换颜色空间的图片
        int m_threshod; //容忍度偏差
       cv:: Vec3b m_model; //要查找的颜色
public :
       cv:: Mat m_result; //最终得到的二值图像
       ColorDetector();
       ~ColorDetector();
        void setModel(cv:: Vec3b & target ); //设置要查找的颜色
       
        void setModel( uchar red , uchar green , uchar blue ); //设置查找颜色的接口,这种颜色值设置在RGB通道上
       
        void setModel2( uchar red , uchar green , uchar blue ); //设置查找颜色的接口,这种颜色值转换到LAB颜色空间上
       
        void setThreshold( int distance ); //设置容忍度的接口
       
        int getDistance(cv:: Vec3b & pixls ); //解算图像像素点与要查找的颜色的距离
       
       cv:: Mat process( const cv:: Mat & image );
       cv:: Mat process2( const cv:: Mat & image );
};
ColorDetector.cpp
#include "ColorDetector.h"
//构造函数,给成员变量初始化,容忍度偏差设为100,查找的三通道颜色默认设为0
ColorDetector ::ColorDetector():m_threshod(100)
{
       m_model [ 0 ] = m_model [ 1 ] = m_model [ 2 ] = 0;
}
ColorDetector ::~ColorDetector()
{
}
void ColorDetector ::setModel(cv:: Vec3b & target )
{
       m_model = target ; //cv::Vec3b类型,三通道
}
void ColorDetector ::setModel( uchar red , uchar green , uchar blue )
{
       m_model [ 0 ] = blue ;
       m_model [ 1 ] = green ;
       m_model [ 2 ] = red ;
}
void ColorDetector ::setModel2( uchar red , uchar green , uchar blue )
{
       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);
}
void ColorDetector ::setThreshold( int distance )
{
       m_threshod = distance ; //设置容忍度
}
//这里的距离公式采用1范数
int ColorDetector ::getDistance(cv:: Vec3b & pixls )
{
        return abs( pixls [ 0 ] - m_model [ 0 ] )
              + abs( pixls [ 1 ] - m_model [ 1 ] )
              + abs( pixls [ 2 ] - m_model [ 2 ] );
}
cv:: Mat ColorDetector ::process( const cv:: Mat & image )
{
       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)
       {
               //循环遍历,把查找到的颜色转换为二值图像,这里按照RGB空间的颜色距离解算
               if (getDistance( * it) < m_threshod)
                      * out = 255;
               else
                      * out = 0;
               ++ it;
               ++ out;
       }
        return m_result;
}
cv:: Mat ColorDetector ::process2( const cv:: Mat & image )
{
       m_result.create( image .size () , CV_8U );
       m_converted.create( image .size () , image .type());
        //把输入图像从RGB颜色空间转换到Lab颜色空间
       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)
       {
               if (getDistance( * it) < m_threshod)
                      * out = 255;
               else
                      * out = 0;
               ++ it;
               ++ out;
       }
        return m_result;
}

main.cpp
#include "ColorDetector.h"
int main()
{
       
       cv:: Mat image = cv::imread( "boldt.jpg" );
        ColorDetector detector; //构造类
       
       detector.setModel(130, 190, 230); //查找蓝天的颜色
       cv::namedWindow( "Process" );
       cv::imshow( "Process" , detector.process(image));
       detector.setModel2(130, 190, 230); //查找蓝天的颜色
       cv::namedWindow( "Process2" );
       cv::imshow( "Process2" , detector.process2(image));
       
       cv::waitKey(0);
        return 0;
}
运行结果:

参考原图:

猜你喜欢

转载自blog.csdn.net/sinat_27614619/article/details/54348579