根据色彩的物体识别方法

本例利用颜色来统计保险丝的个数,分析时利用了图像的HSV空间,通过实验该方法可靠性较高。 
例程分析主要步骤如下: 
1.将图像由RGB格式转换至HSV格式,并将其分离至HSV三个通道。 
2.根据饱和度通道讲保险丝区域分割出来,即ROI区域。 
3.利用ROI区域将保险丝的强度通道分离出来,即使保险丝与背景分离。 
4.不同颜色所对应的的色彩通道的灰度值不同,根据相应色彩的灰度范围 即可区分出不同颜色的保险丝。

本例程的收获主要由以下几点: 
1.针对不同颜色物体的分离、统计、检测等要求可以利用其HSV空间。 
2.在分离ROI区域时,得到Mask区域后可以采用的方法为 A.copyTo(B,Mask)。 
该方法等同于Halcon中的reduce_domain (A, Mask, B)。 
3.在进行阈值分割时OpenCv中没有分割出两个阈值之间区域的算子,因此我采用了以下两种算子来达到相应结果, 
threshold(A, B, min, 255, THRESH_TOZERO) 
threshold(B, B, max, 255, THRESH_TOZERO_INV) 
该方法等同于Halcon中的 threshold(A,B,min,max) 
4.将分割出来的区域的连接的部分分割开,以便进行面积、中心、形状的选择及统计。Halcon中采用的方法为Connection 
OpenCv中采用findContours亦可达到相应的效果。

#include <iostream>     
#include <opencv2/opencv.hpp>  
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;
using namespace std;


int main(int argc, char** argv)
{

        for (int i = 0; i < 5; i++)

        {
            cv::Mat imagecolor, imagehsv, imageh, images, imagev, ROI, HROI, HTarget, cour, Hsg;
            vector<Mat> hsvchannels;
            string file;
            string s;
            char t[256];
            sprintf_s(t, "%02d", i);
            s = t;//int 转化为String

            file = "../data/color/color_fuses_" + s + ".png";
            imagecolor = imread(file);
            if (imagecolor.empty())
                break;

            cvtColor(imagecolor, imagehsv, CV_RGB2HSV);//将图像转换至HSV空间
            split(imagehsv, hsvchannels);
            imageh = hsvchannels.at(0);
            images = hsvchannels.at(1);
            imagev = hsvchannels.at(2);//将HSV通道分离
            threshold(images, ROI, 60, 255, THRESH_BINARY);//利用饱和度通道讲保险丝区域分离,选定ROI区域
            imageh.copyTo(HROI, ROI);//采用色彩通道来区分颜色,因此在H通道分割出ROI区域

            threshold(HROI, HTarget, 110, 255, THRESH_TOZERO);//利用强度通道区分颜色红色110~230、橘黄97~110、黄80~95、绿30~60l、蓝色0~10
            threshold(HTarget, HTarget, 230, 255, THRESH_TOZERO_INV);//分割出两个阈值之间的区域


            blur(HTarget, HTarget, Size(2, 2));//对图像进行平滑去除部分噪声
            threshold(HTarget, HTarget, 110, 255, THRESH_BINARY);
            cv::Mat element25(25, 25, CV_8U, cv::Scalar(1));
            cv::Mat close;
            cv::morphologyEx(HTarget, close, cv::MORPH_CLOSE, element25);

            cv::Mat element15(25, 25, CV_8U, cv::Scalar(1));
            cv::Mat open;
            cv::morphologyEx(close, open, cv::MORPH_OPEN, element15);//分割出目标区域

            vector<vector<Point> > contours;
            vector<Vec4i> hierarchy;
            /// 找到轮廓
            findContours(open, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

            /// 圆形边界框
            vector<vector<Point> > contours_poly(contours.size());

            vector<Point2f>center(contours.size());
            vector<float>radius(contours.size());

            for (int i = 0; i < contours.size(); i++)
            {
                minEnclosingCircle(contours[i], center[i], radius[i]);
            }


            /// 画包围的 圆形框
            Mat drawing = Mat::zeros(imagecolor.size(), CV_8UC3);
            for (int i = 0; i < contours.size(); i++)
            {
                Scalar color = Scalar(0, 0, 255);
                circle(drawing, center[i], (int)radius[i], color, 4, 8, 0);
            }


            Mat drawingroi;//在白色图片上绘制图形不可以简单的相加
            cvtColor(drawing, drawingroi, CV_RGB2GRAY);
            threshold(drawingroi, drawingroi, 20, 255, THRESH_BINARY);

            drawing.copyTo(imagecolor, drawingroi);

            sprintf_s(t,"%01d", contours.size());
            s = t;
            string txt ="Red Fuse : "+ s;
            putText(imagecolor, txt, Point(100, 100), CV_FONT_HERSHEY_COMPLEX, 1,
                Scalar(0, 0, 255), 2, 8);
            imshow("Image", imagecolor);
            waitKey();

    }
    return 0;
}

 
 

--------------------- 
作者:机器视觉专业论坛 
来源:CSDN 
原文:https://blog.csdn.net/Chailiren/article/details/62903369 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/leansmall/article/details/85303827
今日推荐