2014-02-15 316 views
8

我想使用opencv框架平滑输出图像边缘,我正在尝试以下步骤。步骤从这里https://stackoverflow.com/a/17175381/790842使用opencv图像边缘平滑

int lowThreshold = 10.0; 
int ratio = 3; 
int kernel_size = 3; 

Mat src_gray,detected_edges,dst,blurred; 

/// Convert the image to grayscale 
cvtColor(result, src_gray, CV_BGR2GRAY); 

/// Reduce noise with a kernel 3x3 
cv::blur(src_gray, detected_edges, cv::Size(5,5)); 

/// Canny detector 
cv::Canny(detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size); 

//Works fine upto here I am getting perfect edge mask  

cv::dilate(detected_edges, blurred, result); 

//I get Assertion failed (src.channels() == 1 && func != 0) in countNonZero ERROR while doing dilate 

result.copyTo(blurred, blurred); 

cv::blur(blurred, blurred, cv::Size(3.0,3.0)); 

blurred.copyTo(result, detected_edges); 

UIImage *image = [UIImageCVMatConverter UIImageFromCVMat:result]; 

我想帮助我时是否打算在正确的方式,还是我错过什么了?

感谢您的任何建议和帮助。

更新时间:

我有一个像下面一样从grabcut算法得到的,现在我想边缘平滑应用于图像,你可以看到图像不流畅。 enter image description here

+0

@Boyko Perfanov定义我需要在它的帮助。我试图按照您在此处陈述的步骤http://stackoverflow.com/a/17175381/790842 – iphonic

+0

@herohuyongtao你能帮忙吗? – iphonic

+0

@berak你能帮忙吗? – iphonic

回答

17

你想得到这样的东西吗?

enter image description here

如果是的话,那么这里是代码:

#include <iostream> 
#include <vector> 
#include <string> 
#include <fstream> 
#include <opencv2/opencv.hpp> 

using namespace cv; 
using namespace std; 

int main(int argc, char **argv) 
{ 
    cv::namedWindow("result"); 
    Mat img=imread("TestImg.png"); 
    Mat whole_image=imread("D:\\ImagesForTest\\lena.jpg"); 
    whole_image.convertTo(whole_image,CV_32FC3,1.0/255.0); 
    cv::resize(whole_image,whole_image,img.size()); 
    img.convertTo(img,CV_32FC3,1.0/255.0); 

    Mat bg=Mat(img.size(),CV_32FC3); 
    bg=Scalar(1.0,1.0,1.0); 

    // Prepare mask 
    Mat mask; 
    Mat img_gray; 
    cv::cvtColor(img,img_gray,cv::COLOR_BGR2GRAY); 
    img_gray.convertTo(mask,CV_32FC1); 
    threshold(1.0-mask,mask,0.9,1.0,cv::THRESH_BINARY_INV); 

    cv::GaussianBlur(mask,mask,Size(21,21),11.0); 
    imshow("result",mask); 
    cv::waitKey(0); 


     // Reget the image fragment with smoothed mask 
    Mat res; 

    vector<Mat> ch_img(3); 
    vector<Mat> ch_bg(3); 
    cv::split(whole_image,ch_img); 
    cv::split(bg,ch_bg); 
    ch_img[0]=ch_img[0].mul(mask)+ch_bg[0].mul(1.0-mask); 
    ch_img[1]=ch_img[1].mul(mask)+ch_bg[1].mul(1.0-mask); 
    ch_img[2]=ch_img[2].mul(mask)+ch_bg[2].mul(1.0-mask); 
    cv::merge(ch_img,res); 
    cv::merge(ch_bg,bg); 

    imshow("result",res); 
    cv::waitKey(0); 
    cv::destroyAllWindows(); 
} 

而且我认为这个链接也将被interestiong你:Poisson Blending

+0

感谢您的答复,但我不想这样的输出,我已经更新了我的问题,看看你能否帮忙,谢谢。 – iphonic

+0

我改变了我的答案。希望你能理解这个想法。 –

+0

太棒了,我会试一试..谢谢:-) – iphonic

0

我按照以下步骤顺利前景我从GrabCut获得的边缘。

  1. 从我从GrabCut获取的蒙版创建一个二进制图像。
  2. 查找二值图像的轮廓。
  3. 通过绘制轮廓点来创建边缘蒙版。它给出了我从GrabCut获得的前景图像的边界边缘。
  4. 然后按照步骤https://stackoverflow.com/a/17175381/790842