是否有任何功能或算法可以从图像中删除点和小/短线。我为机器人制作了一个公制地图。我用算法从图像中制作骨架。我需要的是,删除小/短线并指向平滑线 - 请参阅picture。我是opencv的新手,所以也许这是一个简单的问题。
有什么建议吗?感谢。
制作骨架我使用此代码
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "highgui.h"
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
int main( int argc, char** argv )
{
cv::Mat img = cv::imread("test4.png", 0);
cv::Mat skel(img.size(), CV_8UC1, cv::Scalar(0));
cv::Mat temp(img.size(), CV_8UC1);
cv::Mat sub_mat = Mat::ones(img.size(), img.type())*255;
cv::Mat eroded;
cv::Mat element = cv::getStructuringElement(cv::MORPH_CROSS,
cv::Size(3, 3));
cv::subtract(sub_mat, img, img);
bool done;
do
{
cv::erode(img, eroded, element);
cv::dilate(eroded, temp, element); // temp = open(img)
cv::subtract(img, temp, temp);
cv::bitwise_or(skel, temp, skel);
eroded.copyTo(img);
done = (cv::countNonZero(img) == 0);
} while (!done);
cv::subtract(sub_mat, skel, skel);
cv:imwrite("skelet.png",skel);
cv::imshow("Skeleton", skel);
cv::waitKey(0);
return 0;
}
答案 0 :(得分:1)
一般来说,为了消除点和噪声,最简单的方法是实现一个中值滤波器(一个基于像素邻域中值的滤波器)。
以下是有关如何在c:
中对其进行编程的示例 Mat median(Mat in)
{
int sizeW = 3;//Neighborhood size
int offset = sizeW/2; //external border of the image
if(in.channels()==3) cvtColor(in,in,CV_BGR2GRAY,1);
in.convertTo(in, CV_8UC1);
//Init
int x,y,i,j,k;
uchar temp;
uchar median[9] = {0};// the size of this matrix = sizeW²
int nRows = in.rows;
int nCols = in.cols;
Mat out = Mat::zeros(nRows-2*offset, nCols-2*offset, CV_8UC1 );
//Processing
for(x=offset; x<nRows-offset; x++)
for(y=offset; y<nCols-offset; y++)
{
//Median
for(i=(-sizeW/2); i<=sizeW/2; i++)
for(j=(-sizeW/2); j<=sizeW/2; j++)
median[(i+sizeW/2)*sizeW + (j+sizeW/2)] = in.at<uchar>(x+i,y+j);
//Sort the median array
for(int z=0; z<sizeW*sizeW; z++)
for(k=1; k<sizeW*sizeW; k++){
if(median[k-1]>median[k]){
temp = median[k-1];
median[k-1] = median[k];
median[k] = temp;
}
}
out.at<uchar>(x-offset,y-offset) = median[(sizeW*sizeW/2)+1];
}// for all pixels
return out;
}
您应该尝试使用邻域尺寸= 3。