使用opencv c ++识别图像中的不同颜色

时间:2015-02-18 06:46:14

标签: c++ opencv

对不起问题的长度

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

 Mat image = imread(argv[1]);
 Mat blank(image.size(), CV_8U, Scalar(0xFF));
 Mat dest;
 imshow("originalimage", image);

 Mat markers(image.size(), CV_8U, Scalar(-1));
 markers(Rect (0, 0, image.cols, 5)) = Scalar::all(1);
 markers(Rect (0, image.rows-5, image.cols, 5)) = Scalar::all(1);
 markers(Rect (0, 0, 5, image.rows)) = Scalar::all(1);
 markers(Rect (image.cols-5, 0, 5, image.rows)) = Scalar::all(1);
 int centreW = image.cols/4;
 int centreH = image.rows/4;
 markers(Rect((image.cols/2)-(centreW/2),(image.rows/2)-(centreH/2), centreW, centreH)) = Scalar::all(2);
 markers.convertTo(markers,CV_BGR2GRAY);
 imshow("markers", markers);

 //Wateshed Segmentation
 WatershedSegmenter segmenter;
 segmenter.setMarkers(markers);
 Mat wshedMask = segmenter.process(image);
 Mat mask;
 convertScaleAbs(wshedMask, mask, 1, 0);
 double thresh = threshold(mask, mask, 1, 255, THRESH_BINARY);
 bitwise_and(image, image, dest, mask);
 dest.convertTo(dest,CV_8U);
 imshow("marker subtracted rgb dest",dest);

 Mat lab;
 cvtColor(dest,lab,CV_BGR2Lab);
 pre();
 imshow("cie lab image",lab);
 for(int i = 0;i < lab.rows;i++){
     for(int j = 0;j < lab.cols;j++){
         double l = lab.at<Vec3b>(i,j)[0];
         double a = lab.at<Vec3b>(i,j)[1];
         double b = lab.at<Vec3b>(i,j)[2];

         if(!(l == 0 && a == 128 && b == 128)){//background color
             double dE1 = numeric_limits<double>::max();
             string result = "";
             node arg;arg.l = l;arg.a = a;arg.b = b;
             for(int k = 0;k < COLORS;k++){
                 double localE1 = CIE94(c_hash[k].value,arg);
                 if(localE1 < dE1){
                     dE1 = localE1;
                     result = c_hash[k].name;
                 }
             }
             cnt[result]++;
         }       
     }
 }
 unordered_map<string,int>::iterator it;
 int local_min = 0;
 string result = "NO Color! Something is fishy";
 for(it = cnt.begin();it != cnt.end();it++){
     if(it->second > 0)cout<<it->first<<endl;
     if(it->second > local_min){
         local_min = it->second;
         result = it->first;
     }
 }
 cout<<"maximum : "<<result<<endl;
 waitKey(0);
 return 0;
}

我首先在图像中识别我的前景对象,然后将目标图像转换为cie lab色彩空间。之后我使用CIE94 deltaE函数找到最接近的标准颜色。但大多数时候答案是黄色,橙色,红色或洋红色,而不管实际的颜色是什么。有人可以告诉我出了什么问题,提前谢谢。

1 个答案:

答案 0 :(得分:0)

BGR图像由三个通道(蓝色,绿色,红色)组成,但您似乎认为它们是单通道图像(具有CV_8U类型),例如:

Mat markers(image.size(), CV_8U, Scalar(-1));
...
markers.convertTo(markers,CV_BGR2GRAY);
...
dest.convertTo(dest,CV_8U);
....
cvtColor(dest,lab,CV_BGR2Lab)