目的:将图像中的像素按照一定放规则分为若干个cluster集合,每个集合包含一类像素
根据算法分为监督学习方法跟无监督学习方法
代码:
#include
#include
#include
#include
using namespace std;
using namespace cv;
int main(int argc, char ** argv)
{
Mat src;
src = imread("E://VS-pro//images//text2.bmp");
imshow("原图", src);
//1.将色背景变为黑色
Mat src_temp;
src.copyTo(src_temp);
for(int row = 0; row < src.rows; row++)
for (int col = 0; col < src.cols; col++)
{
if (src_temp.at(row, col) == Vec3b(255, 255, 255))
{
src_temp.at(row, col) = Vec3b(0, 0, 0);
}
}
imshow("黑色背景", src_temp);
//2.锐化提高对比度
Mat src_lapl;
Mat kernel = (Mat_(3, 3) << 1, 1, 1, 1, -8, 1, 1, 1, 1);
filter2D(src_temp, src_lapl, CV_32F, kernel, Point(-1, -1), 0, BORDER_DEFAULT);
src_temp.convertTo(src_temp, CV_32F);
Mat resultImg = src_temp - src_lapl;
src_temp.convertTo(src_temp, CV_8UC3);
src_lapl.convertTo(src_lapl, CV_8UC3);
resultImg.convertTo(resultImg, CV_8UC3);
imshow("锐化后", resultImg);
//src = resultImg;
//转换为二值图像
Mat src_bin;
cvtColor(resultImg, resultImg, CV_BGR2GRAY);
threshold(resultImg, src_bin, 40, 255, THRESH_BINARY | THRESH_OTSU);
imshow("锐化后转二值", src_bin);
//距离变换
Mat distImg;
distanceTransform(src_bin, distImg, DIST_L1, 3, 5);
normalize(distImg, distImg, 0, 1, NORM_MINMAX);
imshow("距离变换", distImg);
//再次二值化
threshold(distImg, distImg,0.4, 1, THRESH_BINARY);
Mat k1 = Mat::ones(5, 5, CV_8UC1);
imshow("距离变换后二值图像", distImg);
//腐蚀
erode(distImg, distImg, k1, Point(-1, -1));
imshow("腐蚀distImg", distImg);
// markers 找轮廓
Mat dist_8u;
distImg.convertTo(dist_8u, CV_8U);
vector> contours;
findContours(dist_8u, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
// create makers 画轮廓markers标记
Mat markers = Mat::zeros(src_temp.size(), CV_32SC1);
for (size_t i = 0; i < contours.size(); i++) {
drawContours(markers, contours, static_cast(i), Scalar::all(static_cast(i) + 1), -1);
}
circle(markers, Point(5, 5), 3, Scalar(255, 255, 255), -1);
//imshow("my markers", markers);
// perform watershed分水岭
watershed(src, markers);
Mat mark = Mat::zeros(markers.size(), CV_8UC1);
markers.convertTo(mark, CV_8UC1);
bitwise_not(mark, mark, Mat());
imshow("watershed image", mark);
// 分配不同颜色
vector colors;
for (size_t i = 0; i < contours.size(); i++) {
int r = theRNG().uniform(0, 255);
int g = theRNG().uniform(0, 255);
int b = theRNG().uniform(0, 255);
colors.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
}
// 填充颜色
Mat dst = Mat::zeros(markers.size(), CV_8UC3);
for (int row = 0; row < markers.rows; row++) {
for (int col = 0; col < markers.cols; col++) {
int index = markers.at(row, col);
if (index > 0 && index <= static_cast(contours.size())) {
dst.at(row, col) = colors[index - 1];
}
else {
dst.at(row, col) = Vec3b(0, 0, 0);
}
}
}
imshow("Final Result", dst);
waitKey(0);
return 0;
}