【问题标题】:Image edge smoothing with opencv使用opencv进行图像边缘平滑
【发布时间】:2014-03-14 18:36:27
【问题描述】:

我正在尝试使用 opencv 框架平滑输出图像边缘,我正在尝试以下步骤。从这里采取的步骤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];

我需要帮助,无论我是否走对了,或者我错过了什么?

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

更新:

我从 grabcut 算法得到了一个像下面这样的图像,现在我想对图像应用边缘平滑,你可以看到图像不平滑。

【问题讨论】:

  • @Boyko Perfanov 我需要帮助。我正在尝试按照您在此处所述的步骤stackoverflow.com/a/17175381/790842
  • @herohuyongtao 你能帮忙吗?
  • @berak 你能帮忙吗?

标签: c++ ios iphone objective-c opencv


【解决方案1】:

我已按照以下步骤对从 GrabCut 获得的前景边缘进行平滑处理。

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

【讨论】:

    【解决方案2】:

    你想得到这样的东西吗?

    如果是,那么代码如下:

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

    我认为这个链接对你来说也会很有趣:Poisson Blending

    【讨论】:

    • 谢谢你的回答,但我不想要这样的输出,我已经更新了我的问题,看看你能不能帮忙,谢谢。
    • 我改变了我的答案。希望你能明白这个想法。
    • 太好了,我会试一试.. 谢谢:-)
    • 当我尝试实现上述逻辑时,我得到类似i.imgur.com/ClXXpbQ.png?1 的东西,看起来它做事正确,但输出却大不相同。有什么想法吗?
    • 这看起来像是 CV_8UC3/CV_8UC1 和 CV_32FC3/CV_32FC1 图像类型的问题。第一个的范围是 0-255,第二个的范围是 0-1。尝试将您使用的图像转换为 CV_32FC3/CV_32FC1 类型并将其缩放系数 1.0/255.0 。我怀疑您使用的蒙版图像中的值在 0-255 范围内,而不是 0-1。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    • 2016-09-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2019-04-30
    • 2014-01-06
    相关资源
    最近更新 更多