我正在研究图像处理。首先,我必须进行图像分割并仅提取图像的边界。然后,将此图像转换为Freeman链代码。Freeman连锁代码的一部分还可以。但是,当我对图像进行分割时,图像内部仍然是一些不必要的白色像素。因此,下一步,即弗里曼链代码,并不是成功的。我的意思是,由于不需要的像素,它给出了错误的链代码。因此,我必须从图像内部删除多余的像素。我将分享我的代码,您能告诉我如何在此代码中更改或可以为此过滤器编写哪种正确代码?代码在这里:
#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中的所有功能,但无法实现。由于链代码,这非常重要。
好吧,现在我看到了。如前所述,您可以简单地忽略小轮廓。对于其余的,您需要最大的薄轮廓(似乎是4点连接(。在那里您有几个选项:
1(电流变薄。如果您可以抓住Matlab的查找表,则可以将其加载到OpenCV中,因为如何在OpenCV中使用Matlab的512元素查找表阵列?
2(在二进制后用手标记边界像素非常简单。为了提高效率,您可以首先通过在背景上应用连接的组件标签来填充小腔(胰岛((这次使用相反的连接,8个(。
2i&amp;2II(如果您手工进行标签,则可以继续手动收集轮廓向量,也可以切换到cv::findContours
希望这有帮助