根據色彩的物體識別方法

本例利用顏色來統計保險絲的個數,分析時利用了圖像的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 
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章