/* src: input image method: name of noise reduction method that shall be performed "average" ==> moving average "median" ==> median filter "adaptive" ==> edge preserving average filter "bilateral" ==> bilateral filter kSize: (spatial) kernel size param: if method == "adaptive" : threshold ; if method == "bilateral" standard-deviation of radiometric kernel can be ignored otherwise (default value = 0) return: output image */ Mat Dip2::noiseReduction(Mat& src, string method, int kSize, double param){ // apply moving average filter if (method.compare("average") == 0){ return averageFilter(src, kSize); } // apply median filter if (method.compare("median") == 0){ return medianFilter(src, kSize); } // apply adaptive average filter if (method.compare("adaptive") == 0){ return adaptiveFilter(src, kSize, param); } // apply bilateral filter if (method.compare("bilateral") == 0){ return bilateralFilter(src, kSize, param); } // if none of above, throw warning and return copy of original cout << "WARNING: Unknown filtering method! Returning original" << endl; cout << "Press enter to continue" << endl; cin.get(); return src.clone(); }
/* src: input image kSize: window size used by local average threshold: threshold value on differences in order to decide which average to use return: filtered image */ Mat Dip2::adaptiveFilter(Mat& src, int kSize, double threshold){ int local_kSize = 3; Mat mat_avg = averageFilter(src, kSize); Mat mat_local_avg = averageFilter(src, local_kSize); Mat dst = Mat::zeros( src.size(), src.type() ); for (int x = 0; x < src.cols; x++){ for (int y = 0; y < src.rows; y++){ if (mat_local_avg.at<float>(y,x) - mat_avg.at<float>(y,x) < threshold){ dst.at<float>(y,x) = mat_avg.at<float>(y,x);} else dst.at<float>(y,x) = mat_local_avg.at<float>(y,x); } } return dst; // TO DO !! }
/* src: input image kSize: window size used by local average threshold: threshold value on differences in order to decide which average to use return: filtered image */ Mat Dip2::adaptiveFilter(Mat& src, int kSize, double threshold){ Mat average = averageFilter(src, kSize); Mat average3 = averageFilter(src, 3); auto adaptive = [threshold, average, average3](Mat orig, Mat copy, int x, int y) -> Mat { if (abs(average3.at<float>(x, y) - average.at<float>(x, y)) > threshold) { copy.at<float>(x, y) = average3.at<float>(x, y); } else { copy.at<float>(x, y) = average.at<float>(x, y); }; return copy; }; Mat result = forEachMat(average, 1, 1, adaptive); return result; }
// checks basic properties of the filtering result void Dip2::test_averageFilter(void){ Mat input = Mat::ones(9,9, CV_32FC1); input.at<float>(4,4) = 255; Mat output = averageFilter(input, 3); if ( (input.cols != output.cols) || (input.rows != output.rows) ){ cout << "ERROR: Dip2::averageFilter(): input.size != output.size --> Wrong border handling?" << endl; return; } if ( (sum(output.row(0) < 0).val[0] > 0) || (sum(output.row(0) > 255).val[0] > 0) || (sum(output.row(8) < 0).val[0] > 0) || (sum(output.row(8) > 255).val[0] > 0) || (sum(output.col(0) < 0).val[0] > 0) || (sum(output.col(0) > 255).val[0] > 0) || (sum(output.col(8) < 0).val[0] > 0) || (sum(output.col(8) > 255).val[0] > 0) ){ cout << "ERROR: Dip2::averageFilter(): Border of convolution result contains too large/small values --> Wrong border handling?" << endl; return; }else{ if ( (sum(output < 0).val[0] > 0) || (sum(output > 255).val[0] > 0) ){ cout << "ERROR: Dip2::averageFilter(): Convolution result contains too large/small values!" << endl; return; } } float ref[9][9] = {{0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 1, 1, 1, 1, 1, 1, 0}, {0, 1, 1, 1, 1, 1, 1, 1, 0}, {0, 1, 1, (8+255)/9., (8+255)/9., (8+255)/9., 1, 1, 0}, {0, 1, 1, (8+255)/9., (8+255)/9., (8+255)/9., 1, 1, 0}, {0, 1, 1, (8+255)/9., (8+255)/9., (8+255)/9., 1, 1, 0}, {0, 1, 1, 1, 1, 1, 1, 1, 0}, {0, 1, 1, 1, 1, 1, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}}; for(int y=1; y<8; y++){ for(int x=1; x<8; x++){ if (abs(output.at<float>(y,x) - ref[y][x]) > 0.0001){ cout << "ERROR: Dip2::averageFilter(): Result contains wrong values!" << endl; return; } } } cout << "Message: Dip2::averageFilter() seems to be correct" << endl; }
bool filtering::getPreprocessedCloud(pcl::PointCloud<PointType>::Ptr preprocessed_cloud_ptr){ if(number_of_average_clouds_ + number_of_median_clouds_ > cloud_vector_.size()){ std::cout << "There are too few clouds in the input vector, for these filter parameters!" << std::endl; return false; } if(!medianFilter(*preprocessed_cloud_ptr)) return false; if(!averageFilter(*preprocessed_cloud_ptr)) return false; if(!planarSegmentation(preprocessed_cloud_ptr)) std::cout << "Couldn't find a plane!" << std::endl; return true; }