OpenCV读代码笔记: 颜色通道过滤

来源:互联网 发布:沈阳seo关键词 编辑:程序博客网 时间:2024/06/08 17:42
以下函数用于将输入图像中过滤出指定颜色的区域,如果在指定颜色范围内的点显示为白否则为黑, 通常用于找物件的前期准备工作.
//  选择颜色通道, 符合指定颜色范围的点标为亮, 其他标为黑  //  Mat colorMatch(const Mat &src, Mat &match, const Color r,    const bool adaptive_minsv) {    // if use adaptive_minsv    // min value of s and v is adaptive to h    const float max_sv = 255;    const float minref_sv = 64;    const float minabs_sv = 95; //95;    // H range of blue     const int min_blue = 100;  // 100    const int max_blue = 140;  // 140    // H range of yellow    const int min_yellow = 15;  // 15    const int max_yellow = 40;  // 40    // H range of white    const int min_white = 0;   // 15    const int max_white = 30;  // 40    Mat src_hsv;    // convert to HSV space    cvtColor(src, src_hsv, CV_BGR2HSV);    std::vector<cv::Mat> hsvSplit;    split(src_hsv, hsvSplit);    equalizeHist(hsvSplit[2], hsvSplit[2]);    merge(hsvSplit, src_hsv);    // match to find the color    int min_h = 0;    int max_h = 0;    switch (r) {    case BLUE:      min_h = min_blue;      max_h = max_blue;      break;    case YELLOW:      min_h = min_yellow;      max_h = max_yellow;      break;    case WHITE:      min_h = min_white;      max_h = max_white;      break;    default:      // Color::UNKNOWN      break;    }    float diff_h = float((max_h - min_h) / 2); //颜色范围间的差异/2    float avg_h = min_h + diff_h; //颜色平均值    int channels = src_hsv.channels();    int nRows = src_hsv.rows;    // consider multi channel image    int nCols = src_hsv.cols * channels;    if (src_hsv.isContinuous()) {      nCols *= nRows;      nRows = 1;    }    int i, j;    uchar* p;    float s_all = 0;    float v_all = 0;    float count = 0;    for (i = 0; i < nRows; ++i) {      p = src_hsv.ptr<uchar>(i);      for (j = 0; j < nCols; j += 3) {/* http://baike.baidu.com/link?url=DehHScYu92GBMAnO2iz8sch1_xb7T0fQWTqbzlx0HTzxGfH9vBYTGqAW3-3_tVcY7lKkSB5vwzOL605Var8I0qH - 颜色 , S - 饱和度, V - 透明度*/        int H = int(p[j]);      // 0-180        int S = int(p[j + 1]);  // 0-255        int V = int(p[j + 2]);  // 0-255        s_all += S;        v_all += V;        count++;        bool colorMatched = false;        if (H > min_h && H < max_h) {          float Hdiff = 0;          if (H > avg_h)            Hdiff = H - avg_h;          else            Hdiff = avg_h - H;          float Hdiff_p = float(Hdiff) / diff_h;          float min_sv = 0;          if (true == adaptive_minsv)            min_sv =            minref_sv -            minref_sv / 2 *            (1            - Hdiff_p);  // inref_sv - minref_sv / 2 * (1 - Hdiff_p)          else            min_sv = minabs_sv;  // add          if ((S > min_sv && S < max_sv) && (V > min_sv && V < max_sv))            colorMatched = true;        }        if (colorMatched == true) {          p[j] = 0;          p[j + 1] = 0;          p[j + 2] = 255;        }        else {          p[j] = 0;          p[j + 1] = 0;          p[j + 2] = 0;        }      }    }    // cout << "avg_s:" << s_all / count << endl;    // cout << "avg_v:" << v_all / count << endl;    // get the final binary    Mat src_grey;    std::vector<cv::Mat> hsvSplit_done;    split(src_hsv, hsvSplit_done);    src_grey = hsvSplit_done[2];    match = src_grey;    return src_grey;  }

原创粉丝点击