C++ 使用opencv进行图像边缘平滑
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21795643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Image edge smoothing with opencv
提问by iphonic
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
我正在尝试使用 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];
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 grabcutalgorithm, now I want to apply edge smoothening to the image, as you can see the image is not smooth.
我有一个像下面这样的图像从抓取算法中得到,现在我想对图像应用边缘平滑,你可以看到图像不平滑。
回答by Andrey Smorodov
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
我认为这个链接对你来说也会很有趣:泊松混合
回答by Zakir
I have followed the following steps to smooth the edges of the Foreground I got from GrabCut.
我已按照以下步骤平滑从 GrabCut 获得的前景的边缘。
- Create a binary image from the mask I got from GrabCut.
- Find the contour of the binary image.
- Create an Edge Mask by drawing the contour points. It gives the boundary edges of the Foreground image I got from GrabCut.
- Then follow the steps define in https://stackoverflow.com/a/17175381/790842
- 从我从 GrabCut 得到的掩码创建一个二值图像。
- 找到二值图像的轮廓。
- 通过绘制轮廓点创建边缘蒙版。它给出了我从 GrabCut 获得的前景图像的边界边缘。
- 然后按照https://stackoverflow.com/a/17175381/790842 中定义的步骤操作