我正致力于图像处理。首先,我必须进行图像分割并仅提取图像的边界。然后,该图像被转换为自由人链码。自由人链码的部分是好的。但是,当我对图像进行分割时,图像内部仍然存在一些不需要的白色像素。因此,下一步,即自由人链码,并不是成功的。我的意思是,由于不需要的像素,它会给出错误的链码。所以,我必须从图像内部删除不需要的像素。我将分享我的代码,你能告诉我如何改变这段代码或者我应该为这个过滤器编写什么样的正确代码?代码在这里:
#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但我无法实现。由于链码,它非常重要。
答案 0 :(得分:0)
好的,现在我明白了。如上所述,您可以根据长度忽略小轮廓。对于其余部分,您需要最细的轮廓(似乎是4连接就是这种情况)。你有几个选择:
1)减薄电流。如果您可以抓取Matlab的查找表,则可以将其作为How to use Matlab's 512 element lookup table array in OpenCV?
加载到OpenCV中2)在二值化之后用手标记边界像素非常简单。为了提高效率,您可以先在背景上应用连接组件标记来填充小空腔(小岛)(这次使用相反的连接,8)。
2i&amp; 2ii)如果您手动进行标注,您可以手动继续收集轮廓矢量或切换到cv::findContours
希望这有帮助