opencv分水岭算法分割硬币
来源:互联网 发布:韩顺平php视频下载 编辑:程序博客网 时间:2024/05/30 20:09
网上有Python写的,但是没有C++写的,所以自己搞了个,东拼西凑的结果,毕竟我也不是大神,凑活着看吧。倾情奉献,欢迎指教
#include <opencv2/opencv.hpp>
#include <stack>
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <map>
#include <stdio.h>
using namespace std;
using namespace cv;
void icvprCcaBySeedFill(const cv::Mat& _binImg, cv::Mat& _lableImg) //连通域标记,分水岭算法会用到,网上找的程序
{
// connected component analysis (4-component)
// use seed filling algorithm
// 1. begin with a foreground pixel and push its foreground neighbors into a stack;
// 2. pop the top pixel on the stack and label it with the same label until the stack is empty
//
// foreground pixel: _binImg(x,y) = 1
// background pixel: _binImg(x,y) = 0
if (_binImg.empty() ||
_binImg.type() != CV_8UC1)
{
return ;
}
_lableImg.release() ;
_binImg.convertTo(_lableImg, CV_32SC1) ;
int label = 1 ; // start by 2
int rows = _binImg.rows - 1 ;
int cols = _binImg.cols - 1 ;
for (int i = 1; i < rows-1; i++)
{
int* data= _lableImg.ptr<int>(i) ;
for (int j = 1; j < cols-1; j++)
{
if (data[j] == 1)
{
std::stack<std::pair<int,int> > neighborPixels ;
neighborPixels.push(std::pair<int,int>(i,j)) ; // pixel position: <i,j>
++label ; // begin with a new label
while (!neighborPixels.empty())
{
// get the top pixel on the stack and label it with the same label
std::pair<int,int> curPixel = neighborPixels.top() ;
int curX = curPixel.first ;
int curY = curPixel.second ;
_lableImg.at<int>(curX, curY) = label ;
// pop the top pixel
neighborPixels.pop() ;
if (curY != 1 && _lableImg.at<int>(curX, curY-1) == 1) //左值
neighborPixels.push(std::pair<int,int>(curX, curY-1)) ;
if ( curY != rows && _lableImg.at<int>(curX, curY+1) == 1)// 右值
neighborPixels.push(std::pair<int,int>(curX, curY+1)) ;
if (curX != 0 && _lableImg.at<int>(curX-1, curY) == 1)// 上值
neighborPixels.push(std::pair<int,int>(curX-1, curY)) ;
if (curX != cols && _lableImg.at<int>(curX+1, curY) == 1)//下值
neighborPixels.push(std::pair<int,int>(curX+1, curY)) ;
}
}
}
}
}
int main(int argc,char *argv[])
{
Mat image=imread("......图片的地址.........",1);
Mat imageGray;
cvtColor(image,imageGray,CV_BGR2GRAY);
GaussianBlur(imageGray,imageGray,Size(5,5),2); //滤波
threshold(imageGray,imageGray,200,255,CV_THRESH_OTSU|CV_THRESH_BINARY_INV);
imshow("binary",imageGray);
Mat imageThin(imageGray.size(),CV_32FC1); //定义保存距离变换结果的Mat矩阵
distanceTransform(imageGray,imageThin,CV_DIST_L2,3); //距离变换
Mat distShow;
imageThin.convertTo(distShow,CV_8UC1);
normalize(distShow,distShow,0,255,CV_MINMAX); //为了显示清晰,做了0~255归一化
imshow("Source Image",image);
imshow("Thin Image",distShow);
Mat fg,bg,mark0;
Mat element = getStructuringElement(MORPH_RECT, Size(25, 25));
erode(distShow,fg, element);
threshold(fg,fg,200,255,CV_THRESH_OTSU|CV_THRESH_BINARY);
imshow("front Image",fg);
Mat element2 = getStructuringElement(MORPH_RECT, Size(5, 5));
dilate(distShow,bg,element2);
threshold(bg,bg,20,125,CV_THRESH_BINARY_INV);
imshow("bg",bg);
mark0=bg+fg;
imshow("mark0",mark0);
cv::Mat labelImg ;
cv::threshold(mark0, mark0, 130, 1, CV_THRESH_BINARY) ;
icvprCcaBySeedFill(mark0, labelImg) ;
// show result
cv::Mat grayImg ;
labelImg *= 10 ;
labelImg.convertTo(grayImg, CV_8UC1) ;
grayImg=grayImg+bg;
cv::imshow("marker", grayImg) ;
cvtColor(imageGray,imageGray,CV_GRAY2BGR);
Mat marker;
grayImg.convertTo(marker,CV_32SC1);
watershed(imageGray,marker);
Mat afterWatershed;
convertScaleAbs(marker,afterWatershed);
imshow("After Watershed",afterWatershed);
waitKey();
return 0;
}
- opencv分水岭算法分割硬币
- OpenCV分水岭分割算法
- OpenCV 1 图像分割--分水岭算法代码
- opencv分水岭算法对图像进行分割
- Opencv 分水岭算法用于图像分割
- Python之opencv 分水岭分割算法
- opencv-用分水岭算法进行图像分割
- opencv分水岭分割算法C++是
- opencv的分水岭分割
- OpenCV函数cvWatershed图像分割中分水岭算法
- OpenCV函数cvWatershed图像分割中分水岭算法
- OpenCV—图像分割中的分水岭算法原理与应用
- Opencv分水岭算法——watershed自动图像分割用法
- Opencv分水岭算法——watershed自动图像分割用法
- 图像分割 3 opencv分水岭算法源码研究
- opencv之分水岭算法分割及图像修补
- Opencv学习——图像分割之分水岭算法
- Opencv分水岭算法——watershed自动图像分割用法
- AES 256 位 加密
- 高性能网关设备及服务实践(dpdk)--服务器架构研究
- STL源码剖析01-allocator
- JsSIP + WebRTC + freeSWITCH视频会议
- 深度学习在视觉感知中的运用(1)
- opencv分水岭算法分割硬币
- __attribute__((at(0X68000000)))
- javaScript倒计时的实现
- mysql的一个大小写区分的坑
- Redis常用命令
- QT之QTabWidget 为West方向时实现文字垂直显示
- 1141
- C++中对C语言结构体用法的扩充
- axis1.4生成客户端代码