2014-03-13 158 views
0

我有一個灰度圖像,我想裁剪一個大小爲w x h的矩形,以像素(x,y)爲中心。問題是,我不希望裁剪看起來像四方形,所以我希望高斯模糊值,以便它們順利地轉移到零。任何想法如何做到這一點?OpenCV:高斯模糊的裁剪圖像

目前我做的:

int bb_min_x = center_x - width/2.0; 
int bb_max_x = center_x + width/2.0; 

int bb_min_y = center_y - height/2.0; 
int bb_max_y = center_y + height/2.0; 

for(int y = bb_min_y; y <= bb_max_y; y++){ 
    for(int x = bb_min_x; x <= bb_max_x; x++){ 
     final_img.at<uchar>(y,x) = original_img.at<uchar>(y,x); 
    } 
} 
+0

哪些呢「高斯模糊值」是什麼意思?你的描述聽起來像一個簡單的淡出。模糊是不同的,並且模糊的結果也會看起來「四方」。 –

+0

@vlad_tepesch我認爲你是對的,淡出是我之後 – Aly

回答

3

試試這個功能:

從輸入矩形計算距離,並使用它作爲一個衰落的因素。

cv::Mat cropFade(cv::Mat _img, cv::Rect _roi, int _maxFadeDistance) 
{ 
cv::Mat fadeMask = cv::Mat::ones(_img.size(), CV_8UC1); 
cv::rectangle(fadeMask, _roi, cv::Scalar(0),-1); 

cv::imshow("mask",fadeMask>0); 

cv::Mat dt; 
cv::distanceTransform(fadeMask > 0, dt, CV_DIST_L2 ,CV_DIST_MASK_PRECISE); 



// fade to a maximum distance: 
double maxFadeDist; 

if(_maxFadeDistance > 0) 
    maxFadeDist = _maxFadeDistance; 
else 
{ 
    // find min/max vals 
    double min,max; 
    cv::minMaxLoc(dt,&min,&max); 
    maxFadeDist = max; 
} 


//dt = 1.0-(dt* 1.0/max); // values between 0 and 1 since min val should alwaysbe 0 
dt = 1.0-(dt* 1.0/maxFadeDist); // values between 0 and 1 in fading region 

cv::imshow("blending mask", dt); 


cv::Mat imgF; 
_img.convertTo(imgF,CV_32FC3); 


std::vector<cv::Mat> channels; 
cv::split(imgF,channels); 
// multiply pixel value with the quality weights for image 1 
for(unsigned int i=0; i<channels.size(); ++i) 
    channels[i] = channels[i].mul(dt); 

cv::Mat outF; 
cv::merge(channels,outF); 

cv::Mat out; 
outF.convertTo(out,CV_8UC3); 



return out; 
} 

調用與cv::Mat out = cropFade(in, cv::Rect(in.cols/4, in.rows/4, in.cols/2, in.rows/2), in.cols/8);給我莉娜這些結果與指定的矩形:

enter image description here

enter image description here

這是完整的圖像來自同一個不變的RECT褪色結果:

enter image description here

1

如果你把你的邊框轉換爲輪廓您可以使用pointPolygonTest來計算每個像素的邊框邊緣的距離。如果您根據此距離將顏色值降低爲零,則會產生模糊效果。

查看this page舉例。

2

一個簡單的方法:

// Create a weight image 
int border=25; 
cv::Mat_<float> rect=cv::Mat_<float>::zeros(height,width) 
cv::rectangle(rect,cv::Rect(border/2,border/2,width-border,height-border),cv::Scalar(1),-1); 
cv::Mat_<float> weights, kernel=cv::getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(border,border)); 
int nnz = cv::countNonZero(kernel); 
cv::filter2D(rect,weights,-1,kernel/nnz); 

這將創建像下面這樣的權重圖像:

enter image description here

然後你用它來淡出你的形象了:

for(int y = bb_min_y; y <= bb_max_y; y++){ 
    for(int x = bb_min_x; x <= bb_max_x; x++){ 
     float w = weights.at<float>(y-bb_min_y,x-bb_min_x); 
     uchar val = original_img.at<uchar>(y,x); 
     final_img.at<uchar>(y,x) = cv::saturate_cast<uchar>(w*val); 
    } 
}