// ShapeFeatures.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <cstring>
#include <vector>
using namespace std;
using namespace cv;
typedef struct{
long int cir; //周长
long int area; //面积
double R;//圆心度
Point massPt;//重心
vector<Point> inPt; //内部点
vector<Point> edgePt;//边缘点
}Shape; //图形类型
/////////////////////////////////////////////////辅助函数//////////////////////////////////////////////////////////////
//彩色图像灰度化
Mat Color2Gray(Mat const& SrcImg) {
int rows = SrcImg.rows;
int cols = SrcImg.cols;
Mat mGray;
mGray.create(rows, cols, CV_8UC1);
int nMaxValue;
int bValue, gValue, rValue;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
bValue = SrcImg.at<Vec3b>(i, j)[0];
gValue = SrcImg.at<Vec3b>(i, j)[1];
rValue = SrcImg.at<Vec3b>(i, j)[2];
nMaxValue = bValue;
if (nMaxValue < gValue)
{
nMaxValue = gValue;
}
if (nMaxValue < rValue)
{
nMaxValue = rValue;
}
mGray.at<uchar>(i, j) = saturate_cast<uchar>(nMaxValue);
}
}
return mGray;
}
//图像二值化(状态法)
Mat StateMethord(const Mat& srcImg)
{
Mat gray_img, dst;
int cn = srcImg.channels();//通道数
if (cn == 3)
gray_img = Color2Gray(srcImg);
else
gray_img = srcImg.clone();
int height = gray_img.rows;//行数
int width = gray_img.cols;//列数
dst.create(gray_img.size(), gray_img.type());
//峰谷法获取阙值-
int nThreshold = 0, nNewThreshold = 0;
int hist[256]; memset(hist, 0, sizeof(hist));//定义灰度统计数组
int lS1, lS2;//类1,2像素数
double lP1, lP2;//类1,2质量矩
double meanvalue1, meanvalue2;//类1,2灰度均值
int IterationTimes;//迭代次数
int graymax = 255, graymin = 0;//灰度最大最小值
int i, j, k;
for (i = 0; i < height; i++)//统计出各个灰度值的像素数
for (j = 0; j < width; j++) {
int gray = gray_img.at<uchar>(i, j);
hist[gray]++;
}
//给阙值赋迭代初值
nNewThreshold = int((graymax + graymin) / 2);
//迭代求最佳阙值
for (IterationTimes = 0; nThreshold != nNewThreshold && IterationTimes < 100; IterationTimes++)
{
nThreshold = nNewThreshold;
lP1 = lP2 = 0.0;
lS1 = lS2 = 0;
//求类1的质量矩和像素总数
for (k = graymin; k <= nThreshold; k++) {
lP1 += double(k) * hist[k];
lS1 += hist[k];
}
//计算类1均值
meanvalue1 = lP1 / lS1;
//求类2的质量矩和像素总数
for (k = nThreshold + 1; k <= graymax; k++) {
lP2 += double(k) * hist[k];
lS2 += hist[k];
}
//计算类2均值
meanvalue2 = lP2 / lS2;
//获取新的阙值
nNewThreshold = int((meanvalue1 + meanvalue2) / 2);
}
//二值化图像
for (i = 0; i < height; i++)
for (j = 0; j < width; j++) {
if (gray_img.at<uchar>(i, j) < nNewThreshold)
dst.at<uchar>(i, j) = 0;
else dst.at<uchar>(i, j) = 255;
}
return dst;
}
//图像二值化(判断分析法)
Mat OSTU(const Mat& srcImg)
{
//创建灰度图
Mat gray_img, dst;
int cn = srcImg.channels();//通道数
if (cn == 3)
gray_img= Color2Gray(srcImg);
else
gray_img = srcImg.clone();
int height = gray_img.rows;//行数
int width = gray_img.cols;//列数
dst.create(gray_img.size(), gray_img.type());
//判断分析法(Ostu)获取阙值
int nThreshold = 0;
int hist[256]; memset(hist, 0, sizeof(hist));//定义灰度统计数组
int lS, lS1, lS2;//总像素数,类1,2像素数
double lP, lP1;//总质量矩,类1质量矩
double meanvalue1, meanvalue2;//类1,2灰度均值
int IterationTimes;//迭代次数
double Dis1, Dis2, CinDis, CoutDis, max;//方差,类1,类2,组内,组间
int graymax = 255, graymin = 0;//灰度最大最小值
int i, j, k;
//统计出各个灰度值的像素数
for (i = 0; i < height; i++)
for (j = 0; j < width; j++) {
int gray = gray_img.at<uchar>(i, j);
hist[gray]++;
}
lP = 0.0; lS = 0;
if (graymin == 0) graymin++;
//计算总的质量矩lP和像素总数lS
for (k = graymin; k <= graymax; k++) {
lP += double(k) * double(hist[k]);
lS += hist[k];
}
max = 0.0;
lS1 = lS2 = 0;
lP1 = 0.0;
Dis1 = Dis2 = CinDis = CoutDis = 0.0;
double ratio = 0.0;
//求阙值
for (k = graymin; k < graymax; k++) {
lS1 += hist[k];
if (!lS1) { continue; }
lS2 = lS - lS1;
if (lS2 == 0) { break; }
lP1 += double(k) * double(hist[k]);
meanvalue1 = lP1 / lS1;
for (int n = graymin; n <= k; n++)
Dis1 += double((n - meanvalue1) * (n - meanvalue1) * hist[n]);
meanvalue2 = (lP - lP1) / lS2;
for (int m = k + 1; m < graymax; m++)
Dis2 += double((m - meanvalue2) * (m - meanvalue2) * hist[m]);
CinDis = Dis1 + Dis2;
CoutDis = double(lS1) * double(lS2) * (meanvalue1 - meanvalue2) * (meanvalue1 - meanvalue2);
if (CinDis != 0) ratio = CoutDis / CinDis;
if (ratio > max) {
max = ratio; nThreshold = k;
}
}
//二值化图像
for (i = 0; i < height; i++)
for (j = 0; j < width; j++) {
if (gray_img.at<uchar>(i, j) < nThreshold)
dst.at<uchar>(i, j) = 0;
else dst.at<uchar>(i, j) = 255;
}
return dst;
}
//滑动条回调函数
void on_ThreshChange(int, void*)//回调函数
{
}
//找到图形中面积的最值
void findM(vector<Shape>& shapes, long int& areaMax, int& areaMin) {
int max = 0;
int min = 99999999;
for (vector<Shape>::iterator iter = shapes.begin() + 1; iter != shapes.end(); iter++) {
if (min > iter->area) min = iter->area;
if (max < iter->area) max = iter->area;
}
areaMax = max;
areaMin = min;
}
//读取二进制文件
Mat readbyte(const char* path)
{
FILE* fp;
if (fopen_s(&fp, path, "rb") != 0)
{
printf("cannot open file for read\n");
waitKey();//opencv中常用waitKey(n),n<=0表示一直
exit(0);
}
int cols = 2076;
int rows = 2816;
int bands = 3;// 波段数
int pixels = cols * rows * bands;
unsigned char* data = new uchar[pixels * sizeof(uchar)];//uchar等效于char,此处可以借鉴这样的预分配内存方法
fread(data, sizeof(uchar), pixels, fp);//fread函数的用法
fclose(fp);
Mat M(rows, cols, CV_8UC3, Scalar(0, 0, 0));
unsigned char* ptr = M.data;//data是存数据的部分指针
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
for (int k = 0; k < 3; k++)
{
ptr[(i * cols + j) * 3 + k] = data[(i * cols + j) * 3 + k];//BIP
}
}
}
return M;
}
/////////////////////////////////////////////////核心函数////////////////////////////////////////////////////////////
//①连通成分标记
//种子填充法
int Cc_FeedFill(const Mat& binImg, Mat& label)
{
//如果为空或并非单通道图像,则返回-1
if (binImg.empty() || binImg.type() != CV_8UC1)return -1;
int labels = 0;
int cols = binImg.cols;
int rows = binImg.rows;
label = Mat::zeros(rows, cols, CV_8UC1);
vector<int>vt;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (binImg.at<uchar>(i * cols + j) == 255 && label.at<uchar>(i * cols + j) == 0) {
vt.push_back(i * cols + j);
labels++;
while (vt.size() != 0) {
int px = *(vt.end() - 1);
vt.pop_back();
label.at<uchar>(px) = labels;
//查询上下右左是否为连通分量
if (px > cols && binImg.at<uchar>(px - cols) == 255 && label.at<uchar>(px - cols) == 0)
vt.push_back(px - cols);
if (px < (rows - 1) * cols && binImg.at<uchar>(px + cols) == 255 && label.at<uchar>(px + cols) == 0)
vt.push_back(px + cols);
if ((px + 1) % cols != 0 && binImg.at<uchar>(px + 1) == 255 && label.at<uchar>(px + 1) == 0)
vt.push_back(px + 1);
if ((px) % cols != 0 && binImg.at<uchar>(px - 1) == 255 && label.at<uchar>(px -
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
【资源说明】 数字图像处理实训-基于C++实现的图像连通域提取与形状特征分析源码+代码注释.zip数字图像处理实训-基于C++实现的图像连通域提取与形状特征分析源码+代码注释.zip数字图像处理实训-基于C++实现的图像连通域提取与形状特征分析源码+代码注释.zip 数字图像处理实训-基于C++实现的图像连通域提取与形状特征分析源码+代码注释.zip 数字图像处理实训-基于C++实现的图像连通域提取与形状特征分析源码+代码注释.zip 数字图像处理实训-基于C++实现的图像连通域提取与形状特征分析源码+代码注释.zip 数字图像处理实训-基于C++实现的图像连通域提取与形状特征分析源码+代码注释.zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!
资源推荐
资源详情
资源评论


























收起资源包目录






















共 20 条
- 1
资源评论


onnx
- 粉丝: 1w+
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 东北大学MATLAB实验参考答案.doc
- 土木工程知识点-论述市政工程项目管理中的质量控制.doc
- 奕福茶叶网络营销专项方案.doc
- 网络推广方式.pptx
- 信息网络系统施工工艺-secret.doc
- 2023年咨询师继续教育工程项目管理答案.docx
- 现代教育技术网络课程练习题库及答案.doc
- 电子商务网站策划建设方案完全篇范文.doc
- 2023年全国专业技术人员计算机应用能力考试Excel题库版.doc
- 社交网络中谣言传播动力学研究与思考.ppt
- 连锁行业管理信息化.pptx
- 网络媒介对我们学习和生活的影响学风建设主题班会.pptx
- 《电子商务网站规划与建设》课程标准.doc
- 谷歌网络推广方案.doc
- 基因工程诞生的基础.pptx
- 湖北武汉市交管局智慧交通项目施工组织方案.doc
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



安全验证
文档复制为VIP权益,开通VIP直接复制
