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

以下函数用于将输入图像中过滤出指定颜色的区域,如果在指定颜色范围内的点显示为白否则为黑, 通常用于找物件的前期准备工作.

//  选择颜色通道, 符合指定颜色范围的点标为亮, 其他标为黑
  //
  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_tVcY7lKkSB5vwzOL605Var8I0q
		H - 颜色 , 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;
  }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值