簡體   English   中英

使用opencv進行圖像邊緣平滑處理

[英]Image edge smoothing with opencv

我試圖使用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];

無論我是以正確的方式前進,還是我錯過了什么,我都需要幫助?

感謝您的任何建議和幫助。

更新:

我有一個像下面的圖像來自抓取算法,現在我想對圖像應用邊緣平滑,因為你可以看到圖像不平滑。 在此輸入圖像描述

你想得到這樣的東西嗎?

在此輸入圖像描述

如果是,那么這里是代碼:

#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

我按照以下步驟來平滑我從GrabCut獲得的前景的邊緣。

  1. 從我從GrabCut獲得的掩碼創建二進制圖像。
  2. 找到二進制圖像的輪廓。
  3. 通過繪制輪廓點來創建邊緣蒙版。 它給出了我從GrabCut得到的Foreground圖像的邊界邊緣。
  4. 然后按照https://stackoverflow.com/a/17175381/790842中定義的步驟操作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM