OpenCV2计算机视觉编程手册(3)

先设计一个简单的二值化的程序:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

class ColorDetector {

  private:

      // minimum acceptable distance
      int minDist;

      // target color
      cv::Vec3b target;

      // image containing resulting binary map
      cv::Mat result;
public:
      // empty constructor
      ColorDetector() : minDist(100) {

          // default parameter initialization here
          target[0]= target[1]= target[2]= 0;
      }

      // Getters and setters

      // Sets the color distance threshold.
      // Threshold must be positive, otherwise distance threshold
      // is set to 0.
      void setColorDistanceThreshold(int distance) {

          if (distance<0)
              distance=0;
          minDist= distance;
      }

      // Gets the color distance threshold
      int getColorDistanceThreshold() const {

          return minDist;
      }

      // Sets the color to be detected
      void setTargetColor(unsigned char red, unsigned char green, unsigned char blue) {

          target[2]= red;
          target[1]= green;
          target[0]= blue;
      }

      // Sets the color to be detected
      void setTargetColor(cv::Vec3b color) {

          target= color;
      }
      int getDistance(const cv::Vec3b& color) const {
                return abs(color[0]-target[0])+
                       abs(color[1]-target[1])+
                       abs(color[2]-target[2]);
            }
      cv::Mat ColorDetector::process(const cv::Mat &image) {

            // re-allocate binary map if necessary
            // same size as input image, but 1-channel
            result.create(image.rows,image.cols,CV_8U);

            // get the iterators
            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 itout= result.begin<uchar>();

            // for each pixel
            for ( ; it!= itend; ++it, ++itout) {

              // process each pixel ---------------------

                // compute distance from target color
                if (getDistance(*it)<minDist) {

                    *itout= 255;

                } else {

                    *itout= 0;
                }

              // end of pixel processing ----------------
            }

            return result;
      }




     };


int main()
{
    // 1. Create image processor object
    ColorDetector cdetect;
    // 2. Read input image
    cv::Mat image=cv::imread("boldt.jpg");
    if (!image.data)
        return 0;
    // 3. Set input parameters
    cdetect.setTargetColor(130,190,230);//here blue sky
    cv::namedWindow("result");
    // 4. Process the image and display the result
    cv::imshow("result",cdetect.process(image));
    cv::waitKey();
    return 0;
}

效果:

 


接下来。。。。。

策略设计模式就是将算法封装在类中,比如我们见到的进行一个二值化算法;

算法的核心,将像素的颜色与目标颜色比较 ,表示:


// get the iterators
            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 itout=
                                Result.begin<uchar>();

            //for each pixel
            for ( ; it!= itend; ++it, ++itout) {
                // process each pixel -----------------------
                // compute distance from target color
                if (getDistance(*it)<minDist) {
                    *itout= 255;
                } else {
                    *itout= 0;
                }
                // end of pixel processiong -----------------

如何度量颜色距离:

 int getDistance(const cv::Vec3b& color) const {
            return abs(color[0]-target[0])+
                   abs(color[1]-target[1])+
                   abs(color[2]-target[2]);


在ui中拖两个按钮和一个标签,

然后再mainwindow里面添加如下代码:

void MainWindow::on_pushButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,
                tr("Open Image"),".",
              tr("Image File (*.png *.jpg *.jpeg *.bmp)"));
    std::string filename= fileName.toLatin1().data();
    ColorDetectController::getInstance()->setInputImage(filename);
//    cv::imshow("Input Image", ColorDetectController::getInstance()->getInputImage());
//    qimage= ColorDetectController::getInstance()->getInputImage();
    cv::cvtColor(ColorDetectController::getInstance()->getInputImage(),qimage,CV_BGR2RGB);
    // Qt image
    QImage img= QImage((const unsigned char*)(qimage.data),
                               qimage.cols,qimage.rows,QImage::Format_RGB888);
    // display on label
    ui->label->setPixmap(QPixmap::fromImage(img));
    // resize the label to fit the image
    ui->label->resize(ui->label->pixmap()->size());
}

void MainWindow::on_pushButton_2_clicked()
{
    // target color is hard-coded here
    ColorDetectController::getInstance()->setTargetColor(130,190,230);
    // process the input imagr and display result
    ColorDetectController::getInstance()->process();
//    cv::imshow("Output Result", ColorDetectController::getInstance()->getLastResult());
//    cv::cvtColor(ColorDetectController::getInstance()->getLastResult(),qimage,CV_BGR2RGB);
    qimage= ColorDetectController::getInstance()->getLastResult();
    // Qt image
    QImage img= QImage((const unsigned char*)(qimage.data),
                              qimage.cols,qimage.rows,QImage::Format_Indexed8);
    // display on label
    ui->label->setPixmap(QPixmap::fromImage(img));
    // resize the label to fit the image
    ui->label->resize(ui->label->pixmap()->size());
}
如图:



最终运行代码:


并附上部分代码:

colodetectcontroller头文件:

#ifndef COLORDETECTCONTROLLER_H
#define COLORDETECTCONTROLLER_H

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

class ColorDetector {
    private:
        // minimum acceptable distance
        int minDist;
        // target color
        cv::Vec3b target;
        // image containing Resulting binary map
        cv::Mat Result;

    public:
        // empty constructor
        ColorDetector() : minDist(100) {
            // default parameter initialization here
            target[0]= target[1]= target[2]= 0;
        }

        // Sets the color distance threshold.
        // Threshold must be positive,
        // otherwise distance threshold is set to 0.
        void setColorDistanceThreshold(int distance) {
            if (distance<0)
                distance=0;
            minDist= distance;
        }
        // Get the color distance threshold
        int getColorDistanceThreshold() const {
            return minDist;
        }

        // Sets the color to be detected
        void setTargetColor(unsigned char red,
                            unsigned char green,
                            unsigned char blue) {
            // BGR order
            target[2]= red;
            target[1]= green;
            target[0]= blue;
        }

        // Sets the color to be detected
        void setTargetColor(cv::Vec3b color) {
            target= color;
        }

        // Gets the color to be detected
        cv::Vec3b getTargetColor() const {
            return target;
        }

        int getDistance(const cv::Vec3b& color) const {
            return abs(color[0]-target[0])+
                   abs(color[1]-target[1])+
                   abs(color[2]-target[2]);
        }

        cv::Mat ColorDetector::process(const cv::Mat &image) {
            // re-allocate binary map if necessary
            // same size as input image, but 1-channel
            Result.create(image.rows,image.cols,CV_8U);

            // get the iterators
            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 itout=
                                Result.begin<uchar>();

            //for each pixel
            for ( ; it!= itend; ++it, ++itout) {
                // process each pixel -----------------------
                // compute distance from target color
                if (getDistance(*it)<minDist) {
                    *itout= 255;
                } else {
                    *itout= 0;
                }
                // end of pixel processiong -----------------
            }
            return Result;
        }
};

class ColorDetectController {
    private:
        // the algorithm class
        ColorDetector *cdetect;
        cv::Mat image;	// The image to be processed
        cv::Mat Result;	// The image Result
        // pointer to the singleton
        static ColorDetectController *singleton;

        // private constructor
        ColorDetectController() {
            // setting up the application
            cdetect= new ColorDetector();
        }


    public:
        // Get sccess to Singleton instance
        static ColorDetectController *getInstance() {
            //Creates the instance at first call
            if (singleton == 0)
                singleton= new ColorDetectController;
            return singleton;
        }

        //Release the singleton instance of this controller
        static void destroy() {
            if (singleton != 0) {
                delete singleton;
                singleton= 0;
            }
        }

        // Set the color distance threshold
        void setColorDestanceThreshold(int distance) {
            cdetect->setColorDistanceThreshold(distance);
        }

        // Get the color distance threshold
        int getColorDistanceThreshold() const {
            return cdetect->getColorDistanceThreshold();
        }

        //Set the color to be detected
        void setTargetColor(unsigned char red,
            unsigned char green,unsigned char blue) {
            cdetect->setTargetColor(red,green,blue);
        }

        // Get the color to be detected
        void getTargetColor(unsigned char &red,
            unsigned char &green,unsigned char &blue) const {
            cv::Vec3b color= cdetect->getTargetColor();
            red= color[2];
            green= color[1];
            blue= color[0];
        }

        // Set the input image. Reads it fram file.
        bool setInputImage(std::string filename) {
            image= cv::imread(filename);
            if (!image.data)
                return false;
            else
                return true;
        }

        // Return the current input image.
        const cv::Mat getInputImage() const {
            return image;
        }

        // Perform image procesing.
        void process() {
            Result= cdetect->process(image);
        }

        // Return the image Result from the latest processing.
        const cv::Mat getLastResult() const {
            return Result;
        }

        // Detects processor objects created by the controller.
        ~ColorDetectController() {
            delete cdetect;
        }
};
#endif // COLORDETECTCONTROLLER_H

差不多就这些。。。折腾了好一会。。




  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值