Image edge smoothing with opencv

匿名 (未验证) 提交于 2019-12-03 02:45:02

问题:

I am trying to smooth output image edges using opencv framework, I am trying following steps. Steps took from here https://stackoverflow.com/a/17175381/790842

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]; 

I want help whether if I am going in right way, or what am I missing?

Thanks for any suggestion and help.

Updated:

I have got an image like below got from grabcut algorithm, now I want to apply edge smoothening to the image, as you can see the image is not smooth.

回答1:

Do you want to get something like this?

If yes, then here is the code:

#include  #include  #include  #include  #include   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 ch_img(3);     vector 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(); } 

And I think this link will be interestiong for you too: Poisson Blending



回答2:

I have followed the following steps to smooth the edges of the Foreground I got from GrabCut.

  1. Create a binary image from the mask I got from GrabCut.
  2. Find the contour of the binary image.
  3. Create an Edge Mask by drawing the contour points. It gives the boundary edges of the Foreground image I got from GrabCut.
  4. Then follow the steps define in https://stackoverflow.com/a/17175381/790842


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!