【发布时间】:2018-09-10 06:57:22
【问题描述】:
我正在研究图像处理。首先,我必须进行图像分割并仅提取图像的边界。然后,将此图像转换为freeman链码。 freeman 链码部分就OK了。但是,当我对图像进行分割时,图像内部仍然存在一些不需要的白色像素。因此,下一步,即弗里曼链码,并没有成功。我的意思是,由于不需要的像素,它给出了不正确的链码。所以,我必须从图像内部删除不需要的像素。我将分享我的代码,您能告诉我如何更改此代码,或者我应该为这个过滤器编写什么样的正确代码?代码在这里:
#include <opencv2/opencv.hpp>
#include <vector>
#include <iostream>
#include <opencv2/imgproc/imgproc_c.h>
using namespace cv;
using namespace std;
int main(){
Mat img = imread("<image-path>");
Mat gray;
cvtColor(img,gray,CV_BGR2GRAY);
Mat binary;
threshold(gray,binary, 200, 255, CV_THRESH_BINARY);
Mat kernel = (Mat_<float>(3,3) <<
1, 1, 1,
1, -8, 1,
1, 1, 1);
Mat imgLaplacian;
Mat sharp= binary;
filter2D(binary, imgLaplacian, CV_32F, kernel);
binary.convertTo(sharp, CV_32F);
Mat imgResult = sharp - imgLaplacian;
imgResult.convertTo(imgResult, CV_8UC1);
imgLaplacian.convertTo(imgLaplacian, CV_8UC1);
//Find contours
vector<vector<Point>> contours;
vector <uchar> chaincode;
vector <char> relative;
findContours(imgLaplacian,contours, CV_RETR_LIST, CHAIN_APPROX_NONE);
for (size_t i=0; i<contours.size();i++){
chain_freeman(contours[i],chaincode);
FileStorage fs("<file-path>", 1);
fs << "chain" << chaincode;
}
for (size_t i=0; i<chaincode.size()-1; i++){
int relative1 = 0;
relative1 = abs(chaincode[i]-chaincode[i+1]);
cout << relative1;
for (int j=0; j<relative1; j++){
}
relative.push_back(relative1);
FileStorage fs("<file-path>", 1);
fs << "chain" << relative;
}
imshow("binary",imgLaplacian);
cvWaitKey();
return 0;
}
在这个结果中,我想删除图像内部的白色像素。我在opencv中尝试了所有fiter,但我无法实现。由于链码,它非常重要。
【问题讨论】:
-
cv::findContours不是已经给了你一个轮廓列表,其中每个的大小描述了轮廓的长度吗?如果是单个像素外的 8 连接,则由四个元素组成。或者只是变形关闭或使用连接组件标签预先填充孔。 -
我试过了,但它没有用,或者我不能用它。我使用了 morph close 但结果仍然相同。
-
也许您可以发布您希望实现的图像?但是在阈值之后对二值图像使用
cv::findContours,这里不需要边缘检测器。 -
@mainactual 好的,我在帖子上进行了编辑。你可以检查一下。
标签: c++ opencv image-processing image-segmentation