Tags: DIP
photoshop USM锐化有3个参数:半径,数量,预值。
这里参考这篇文章使用c++实现,并观察效果。
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/photo/photo.hpp>
cv::Mat img;
int radius = 1;
int amount = 20;
int threshold = 0;
cv::Mat myPsUSM(const cv::Mat& src, int radius, int amount, int threshold){
int width = src.rows;
int height = src.cols;
cv::Mat temp;
cv::Mat result = src.clone();
if (radius % 2 == 0){
radius += 1;
}
cv::GaussianBlur(src, temp, cv::Size(radius, radius), 0, 0);
for(int x=0; x<height; x++){
for(int y=0; y<width; y++){
int value = src.at<uchar>(x,y) - temp.at<uchar>(x,y);
if(abs(value) > threshold){
// saturate_cast防止数据溢出
result.at<uchar>(x,y) = cv::saturate_cast<uchar>(src.at<uchar>(x,y) + int(amount*value/100));
}
}
}
return result;
}
void onTrackbar(int, void*){
cv::Mat result;
std::vector<cv::Mat> rgbchannels(3);
cv::split(img, rgbchannels);
rgbchannels[0] = myPsUSM(rgbchannels[0], radius, amount, threshold);
rgbchannels[1] = myPsUSM(rgbchannels[1], radius, amount, threshold);
rgbchannels[2] = myPsUSM(rgbchannels[2], radius, amount, threshold);
cv::merge(rgbchannels,result);
cv::imshow("result",result);
cv::waitKey(0);
}
int main(){
img = cv::imread("/Users/yuhua.cheng/Documents/data/Lenna.png",-1);
if(img.empty()){
std::cout << "Unable to load image!" << std::endl;
return -1;
}
cv::cvtColor(img, img, cv::COLOR_BGRA2BGR);
std::vector<cv::Mat> rgbchannels(3);
cv::split(img, rgbchannels);
cv::namedWindow("result", 0);
cv::createTrackbar("radius","result", &radius, 40, onTrackbar);
cv::createTrackbar("amount","result", &amount, 100, onTrackbar);
cv::createTrackbar("threshold","result", &threshold, 40, onTrackbar);
onTrackbar(0,0);
return 0;
}