OpenCV 带掩膜的Gauss平滑/滤波

来源:互联网 发布:java求3个最小公倍数 编辑:程序博客网 时间:2024/06/05 22:45

OpenCV 提供完整而丰富的图像平滑滤波算进接口,但这些平滑都是对整幅图像或者整幅图像中的某个ROI区域进行的,而有些时候我们需要仅仅对某个掩膜区域内的亮度或者数据进行平滑或者滤波,下面给出了常用的Gauss平滑滤波在带有掩膜时的一种实现(图像的数据类型为CV_32F1,其它类型的图像数据可仿照实现)

void MaskGaussianBlur(cv::InputArray _src, cv::InputArray _mask, cv::OutputArray _dst, cv::Size ksize, double sigmaX, double sigmaY){cv::Mat src = _src.getMat();cv::Mat mask = _mask.getMat();_dst.create(src.size(), src.type());cv::Mat dst = _dst.getMat();if (src.channels() != 1)return;if (ksize.width == 1 && ksize.height == 1){src.copyTo(dst);return;}else{if (ksize.width == 1){MaskGuassianBlur1D(src, mask, dst, ksize.height, sigmaY, true);return;}if (ksize.height == 1){MaskGuassianBlur1D(src, mask, dst, ksize.width,  sigmaX, false);return;}cv::Mat temp(src.size(), src.type());MaskGuassianBlur1D(src, mask, temp, ksize.height, sigmaY, true);MaskGuassianBlur1D(temp, mask, dst, ksize.width,  sigmaX, false);}}void GuassianKernel(double *kernel, int size, double sigma){double *data = kernel;for (int i = 0; i < size; i ++){double index = (size / 2) - i;*(data + i) = exp(-(index * index) / (2 * sigma * sigma + 1e-6));}}void MaskGuassianBlur1D(cv::Mat img, cv::Mat imgMask, cv::Mat &dst, int size, double sigma, bool flgCol){double *kernel = new double[size];GuassianKernel(kernel, size, sigma);double thre = 10;cv::Mat src, mask;//转置if(flgCol){src = img.t();mask = imgMask.t();}else{src = img;mask = imgMask;}int w = src.cols;int h = src.rows;int tw = w - size;cv::Mat imgDst = cv::Mat::zeros(h, w, CV_32F);for (int i = 0; i < h; i ++){uchar *datMask = mask.ptr<uchar>(i);float *datSrc = src.ptr<float>(i);float *datDst = imgDst.ptr<float>(i);for (int j = size; j < tw; j ++){if(datMask[j] <= 0)continue;double sum = 0;double kSum = 0;//核计数int hsize = size / 2;for (int k = -hsize; k <= hsize; k ++){if(datMask[j + k] > 0){double diff = fabs(datSrc[j] - datSrc[j + k]);if(diff < thre){sum += kernel[k + hsize] * datSrc[j + k];kSum += kernel[k + hsize];}}}datDst[j] = float (sum / kSum);}}if(flgCol){cv::Mat tDst = imgDst.t();dst = tDst.clone();}elsedst = imgDst.clone();delete [] kernel;}


原创粉丝点击