简体   繁体   English

使用opencv进行图像边缘平滑处理

[英]Image edge smoothing with opencv

I am trying to smooth output image edges using opencv framework, I am trying following steps. 我试图使用opencv框架平滑输出图像边缘,我正在尝试以下步骤。 Steps took from here https://stackoverflow.com/a/17175381/790842 步骤来自这里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. 我有一个像下面的图像来自抓取算法,现在我想对图像应用边缘平滑,因为你可以看到图像不平滑。 在此输入图像描述

Do you want to get something like this? 你想得到这样的东西吗?

在此输入图像描述

If yes, then here is the code: 如果是,那么这里是代码:

#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();
}

And I think this link will be interestiong for you too: Poisson Blending 而且我认为这个链接对你来说也很有意义: Poisson Blending

I have followed the following steps to smooth the edges of the Foreground I got from GrabCut. 我按照以下步骤来平滑我从GrabCut获得的前景的边缘。

  1. Create a binary image from the mask I got from GrabCut. 从我从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. 它给出了我从GrabCut得到的Foreground图像的边界边缘。
  4. Then follow the steps define in https://stackoverflow.com/a/17175381/790842 然后按照https://stackoverflow.com/a/17175381/790842中定义的步骤操作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM