Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Alpha-Dependent Template Matching

I have a couple of pics that are either 8UC3 or 8UC4 and I would like to template match them almost exactly. I have done this in my code, and I would like to learn if there are better methods to optimize and simplify the code? In also know that it is currently done with block methods and fft, and also I have read about phase ma(CUDA's next, but this will do for now). I think I have moved everything out of the loop that is possible. Breaking during GDB sessions usually end up on the multiply or the merge in the loop. I also haven't guarded against all possible values of different types and perhaps there are better ways to guard against different types? (I think my code will fail for graychannel with alpha). Last, what is the best way to guard against matching against a black patch since everything will be 0.

I have also referred to these codes, but I developed my own:

Thanks

alpha-dependent template matching

opencv template matching and transparency

Mat templ = _templ.getMat();
Mat img = _img.getMat();
const double UCHARMAX = 255;
const double UCHARMAXINV = 1./UCHARMAX;
Mat templRed(templ.size(), CV_8UC1);
Mat templGreen(templ.size(), CV_8UC1);
Mat templBlue(templ.size(), CV_8UC1);
Mat templAlpha(templ.size(), CV_8UC1);

Mat imgRed(img.size(), CV_8UC1);
Mat imgGreen(img.size(), CV_8UC1);
Mat imgBlue(img.size(), CV_8UC1);
Mat imgAlpha(img.size(), CV_8UC1);
if(templ.depth() == CV_8U && img.depth() == CV_8U && 
  (img.type() == CV_8UC3 || img.type() == CV_8UC4) &&
  (templ.type() == CV_8UC3 || templ.type() == CV_8UC4)){
  if(templ.type() == CV_8UC3){
    templAlpha = Scalar(UCHARMAX);
    cvSplit(&templ, &templRed, &templGreen, &templBlue, NULL);
  }
  else if(templ.type() == CV_8UC4){
    cvSplit(&templ, &templBlue, &templGreen, &templRed, &templAlpha);
  }
  if(img.type() == CV_8UC3){
    imgAlpha = Scalar(UCHARMAX);
    cvSplit(&img, &imgRed, &imgGreen, &imgBlue, NULL);
  }
  else if(templ.type() == CV_8UC4){
    cvSplit(&img, &imgBlue, &imgGreen, &imgRed, &imgAlpha);
  }
  Size corrSize(img.cols - templ.cols + 1, img.rows - templ.rows + 1);
  _result.create(corrSize, CV_32F);
  Mat result = _result.getMat();

  Mat tempRed=templRed.clone();
  Mat tempBlue=templBlue.clone();
  Mat tempGreen=templGreen.clone();

  multiply(tempRed, templAlpha, tempRed, UCHARMAXINV);
  multiply(tempGreen, templAlpha, tempGreen, UCHARMAXINV);
  multiply(tempBlue, templAlpha, tempBlue, UCHARMAXINV);

  multiply(imgRed, imgAlpha, imgRed, UCHARMAXINV);
  multiply(imgGreen, imgAlpha, imgGreen, UCHARMAXINV);
  multiply(imgBlue, imgAlpha, imgBlue, UCHARMAXINV);

  Mat temp(templ.size(), CV_8UC3);
  cvMerge(&tempBlue, &tempGreen, &tempRed, NULL, &temp);
  const double tempsum2 = norm(temp);

  Mat ROI(templ.size(), CV_8UC3);

  for(int i=0; i<img.rows-templ.rows; i++){
    for(int j=0; j<img.cols-templ.cols; j++){

      const Rect rect = Rect(j, i, templ.cols, templ.rows);
      Mat ROItempRed(imgRed, rect);
      Mat ROItempGreen(imgGreen, rect);
      Mat ROItempBlue(imgBlue, rect);

      Mat ROIRed = ROItempRed.clone();
      Mat ROIBlue = ROItempBlue.clone();
      Mat ROIGreen = ROItempGreen.clone();

      multiply(ROIRed, templAlpha, ROIRed, UCHARMAXINV);
      multiply(ROIGreen, templAlpha, ROIGreen, UCHARMAXINV);
      multiply(ROIBlue, templAlpha, ROIBlue, UCHARMAXINV);

      cvMerge(&ROIBlue, &ROIGreen, &ROIRed, NULL, &ROI);
      Mat corr(result, Rect(j, i, 1, 1));
      crossCorr( ROI, temp, corr, corr.size(), corr.type(), Point(0,0), 0, 0);
      const double normalization = norm(ROI)*tempsum2;
      if(normalization != 0)
        corr /= normalization;
      else
        corr = 0.; //How should black be matched?
    }
  }
}
//...  else do regular correlation match

Alpha-Dependent Template Matching

I have a couple of pics that are either 8UC3 or 8UC4 and I would like to template match them almost exactly. I have done this in my code, and I would like to learn if there are better methods to optimize and simplify the code? In also know that it is currently done with block methods and fft, and also I have read about phase ma(CUDA's based matching. (CUDA's next, but this will do for now). I think I have moved everything out of the loop that is possible. Breaking during GDB sessions usually end up on the multiply or the merge in the loop. I also haven't guarded against all possible values of different types and perhaps there are better ways to guard against different types? (I think my code will fail for graychannel with alpha). Last, what is the best way to guard against matching against a black patch since everything will be 0.

I have also referred to these codes, but I developed my own:

Thanks

alpha-dependent template matching

opencv template matching and transparency

Mat templ = _templ.getMat();
Mat img = _img.getMat();
const double UCHARMAX = 255;
const double UCHARMAXINV = 1./UCHARMAX;
Mat templRed(templ.size(), CV_8UC1);
Mat templGreen(templ.size(), CV_8UC1);
Mat templBlue(templ.size(), CV_8UC1);
Mat templAlpha(templ.size(), CV_8UC1);

Mat imgRed(img.size(), CV_8UC1);
Mat imgGreen(img.size(), CV_8UC1);
Mat imgBlue(img.size(), CV_8UC1);
Mat imgAlpha(img.size(), CV_8UC1);
if(templ.depth() == CV_8U && img.depth() == CV_8U && 
  (img.type() == CV_8UC3 || img.type() == CV_8UC4) &&
  (templ.type() == CV_8UC3 || templ.type() == CV_8UC4)){
  if(templ.type() == CV_8UC3){
    templAlpha = Scalar(UCHARMAX);
    cvSplit(&templ, &templRed, &templGreen, &templBlue, NULL);
  }
  else if(templ.type() == CV_8UC4){
    cvSplit(&templ, &templBlue, &templGreen, &templRed, &templAlpha);
  }
  if(img.type() == CV_8UC3){
    imgAlpha = Scalar(UCHARMAX);
    cvSplit(&img, &imgRed, &imgGreen, &imgBlue, NULL);
  }
  else if(templ.type() == CV_8UC4){
    cvSplit(&img, &imgBlue, &imgGreen, &imgRed, &imgAlpha);
  }
  Size corrSize(img.cols - templ.cols + 1, img.rows - templ.rows + 1);
  _result.create(corrSize, CV_32F);
  Mat result = _result.getMat();

  Mat tempRed=templRed.clone();
  Mat tempBlue=templBlue.clone();
  Mat tempGreen=templGreen.clone();

  multiply(tempRed, templAlpha, tempRed, UCHARMAXINV);
  multiply(tempGreen, templAlpha, tempGreen, UCHARMAXINV);
  multiply(tempBlue, templAlpha, tempBlue, UCHARMAXINV);

  multiply(imgRed, imgAlpha, imgRed, UCHARMAXINV);
  multiply(imgGreen, imgAlpha, imgGreen, UCHARMAXINV);
  multiply(imgBlue, imgAlpha, imgBlue, UCHARMAXINV);

  Mat temp(templ.size(), CV_8UC3);
  cvMerge(&tempBlue, &tempGreen, &tempRed, NULL, &temp);
  const double tempsum2 = norm(temp);

  Mat ROI(templ.size(), CV_8UC3);

  for(int i=0; i<img.rows-templ.rows; i++){
    for(int j=0; j<img.cols-templ.cols; j++){

      const Rect rect = Rect(j, i, templ.cols, templ.rows);
      Mat ROItempRed(imgRed, rect);
      Mat ROItempGreen(imgGreen, rect);
      Mat ROItempBlue(imgBlue, rect);

      Mat ROIRed = ROItempRed.clone();
      Mat ROIBlue = ROItempBlue.clone();
      Mat ROIGreen = ROItempGreen.clone();

      multiply(ROIRed, templAlpha, ROIRed, UCHARMAXINV);
      multiply(ROIGreen, templAlpha, ROIGreen, UCHARMAXINV);
      multiply(ROIBlue, templAlpha, ROIBlue, UCHARMAXINV);

      cvMerge(&ROIBlue, &ROIGreen, &ROIRed, NULL, &ROI);
      Mat corr(result, Rect(j, i, 1, 1));
      crossCorr( ROI, temp, corr, corr.size(), corr.type(), Point(0,0), 0, 0);
      const double normalization = norm(ROI)*tempsum2;
      if(normalization != 0)
        corr /= normalization;
      else
        corr = 0.; //How should black be matched?
    }
  }
}
//...  else do regular correlation match