develop #18

Merged
dmoco merged 2 commits from :develop into develop 2024-12-17 05:38:36 -05:00
Showing only changes of commit d16483caf1 - Show all commits

View File

@ -2,7 +2,7 @@
#include <iostream> #include <iostream>
//区域生长算法 //区域生长算法
int RegionGrow(cv::Mat& src, cv::Mat& matDst, cv::Point2i pt, int th) int RegionGrow(cv::Mat& src, cv::Mat& matDst, cv::Point2i pt, int th)
{ {
cv::Point2i ptGrowing; cv::Point2i ptGrowing;
@ -16,39 +16,39 @@ int RegionGrow(cv::Mat& src, cv::Mat& matDst, cv::Point2i pt, int th)
vcGrowPt.push_back(pt); vcGrowPt.push_back(pt);
matDst.at<uchar>(pt.y, pt.x) = 255; matDst.at<uchar>(pt.y, pt.x) = 255;
while (!vcGrowPt.empty()) //生长栈不为空则生长 while (!vcGrowPt.empty()) //生长栈不为空则生长
{ {
pt = vcGrowPt.back(); //取出一个生长点 pt = vcGrowPt.back(); //取出一个生长点
vcGrowPt.pop_back(); vcGrowPt.pop_back();
std::vector<cv::Point2i> temp_vcGrowPt; //临时生长点栈 std::vector<cv::Point2i> temp_vcGrowPt; //临时生长点栈
int temp_vcGrowPt_size = 0; //可生长方向数量因为存在被其余生长点先生长情况不可直接使用temp_vcGrowPt.size() int temp_vcGrowPt_size = 0; //可生长方向数量因为存在被其余生长点先生长情况不可直接使用temp_vcGrowPt.size()
nSrcValue = src.at<uchar>(pt.y, pt.x); nSrcValue = src.at<uchar>(pt.y, pt.x);
//分别对八个方向上的点进行生长 //分别对八个方向上的点进行生长
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
{ {
ptGrowing.x = pt.x + DIR[i][0]; ptGrowing.x = pt.x + DIR[i][0];
ptGrowing.y = pt.y + DIR[i][1]; ptGrowing.y = pt.y + DIR[i][1];
//检查是否是边缘点 //检查是否是边缘点
if (ptGrowing.x < 0 || ptGrowing.y < 0 || ptGrowing.x >(src.cols - 1) || (ptGrowing.y > src.rows - 1)) if (ptGrowing.x < 0 || ptGrowing.y < 0 || ptGrowing.x >(src.cols - 1) || (ptGrowing.y > src.rows - 1))
continue; continue;
nGrowLable = matDst.at<uchar>(ptGrowing.y, ptGrowing.x); //当前待生长点的灰度值 nGrowLable = matDst.at<uchar>(ptGrowing.y, ptGrowing.x); //当前待生长点的灰度值
if (nGrowLable == 0) //如果标记点还没有被生长 if (nGrowLable == 0) //如果标记点还没有被生长
{ {
nCurValue = src.at<uchar>(ptGrowing.y, ptGrowing.x); nCurValue = src.at<uchar>(ptGrowing.y, ptGrowing.x);
if (abs(nCurValue - nSrcValue) < th) //在阈值范围内则生长 if (abs(nCurValue - nSrcValue) < th) //在阈值范围内则生长
{ {
// matDst.at<uchar>(ptGrowing.y, ptGrowing.x) = 255; // matDst.at<uchar>(ptGrowing.y, ptGrowing.x) = 255;
temp_vcGrowPt_size++; temp_vcGrowPt_size++;
temp_vcGrowPt.push_back(ptGrowing); //将下一个生长点压入栈中 temp_vcGrowPt.push_back(ptGrowing); //将下一个生长点压入栈中
} }
} }
else { else {
temp_vcGrowPt_size++; temp_vcGrowPt_size++;
} }
} }
//相邻的生长点不是单向生长,则生长点有效 //相邻的生长点不是单向生长,则生长点有效
if (temp_vcGrowPt_size >= 1) { if (temp_vcGrowPt_size >= 1) {
mat_cnt++; mat_cnt++;
matDst.at<uchar>(pt.y, pt.x) = 255; matDst.at<uchar>(pt.y, pt.x) = 255;
@ -56,43 +56,43 @@ int RegionGrow(cv::Mat& src, cv::Mat& matDst, cv::Point2i pt, int th)
} }
} }
return mat_cnt; return mat_cnt;
// bitwise_and(src, matDst, matDst); //与运算可以保留原图像数据 // bitwise_and(src, matDst, matDst); //与运算可以保留原图像数据
} }
// 定义拟合圆形的函数 // 定义拟合圆形的函数
void FitCircleCenter(vector<Point>& Circle_Data, Point2f& Circle_Center, float& Circle_R) void FitCircleCenter(vector<Point>& Circle_Data, Point2f& Circle_Center, float& Circle_R)
{ {
//定义计算中间变量 //定义计算中间变量
double sumX1 = 0.0; //代表Xi的和(从1~n) X1代表X的1次方 double sumX1 = 0.0; //代表Xi的和(从1~n) X1代表X的1次方
double sumY1 = 0.0; double sumY1 = 0.0;
double sumX2 = 0.0; //代表(Xi)^2的和(i从1~n)X2代表X的二次方 double sumX2 = 0.0; //代表(Xi)^2的和(i从1~n)X2代表X的二次方
double sumY2 = 0.0; double sumY2 = 0.0;
double sumX3 = 0.0; double sumX3 = 0.0;
double sumY3 = 0.0; double sumY3 = 0.0;
double sumX1Y1 = 0.0; double sumX1Y1 = 0.0;
double sumX1Y2 = 0.0; double sumX1Y2 = 0.0;
double sumX2Y1 = 0.0; double sumX2Y1 = 0.0;
const double N = (double)Circle_Data.size();//获得输入点的个数 const double N = (double)Circle_Data.size();//获得输入点的个数
for (int i = 0; i < Circle_Data.size(); ++i)//遍历组中所有数据 for (int i = 0; i < Circle_Data.size(); ++i)//遍历组中所有数据
{ {
double x = 0; double x = 0;
double y = 0; double y = 0;
x = Circle_Data[i].x; //获得组中第i个点的x坐标 x = Circle_Data[i].x; //获得组中第i个点的x坐标
y = Circle_Data[i].y; //获得组中第i个点的y坐标 y = Circle_Data[i].y; //获得组中第i个点的y坐标
double x2 = x * x; //计算x^2 double x2 = x * x; //计算x^2
double y2 = y * y; //计算y^2 double y2 = y * y; //计算y^2
double x3 = x2 * x; //计算x^3 double x3 = x2 * x; //计算x^3
double y3 = y2 * y; //计算y^3 double y3 = y2 * y; //计算y^3
double xy = x * y; //计算xy double xy = x * y; //计算xy
double x1y2 = x * y2; //计算x*y^2 double x1y2 = x * y2; //计算x*y^2
double x2y1 = x2 * y; //计算x^2*y double x2y1 = x2 * y; //计算x^2*y
sumX1 += x; //sumX=sumX+x;计算x坐标的和 sumX1 += x; //sumX=sumX+x;计算x坐标的和
sumY1 += y; //sumY=sumY+y;计算y坐标的和 sumY1 += y; //sumY=sumY+y;计算y坐标的和
sumX2 += x2; //计算x^2的和 sumX2 += x2; //计算x^2的和
sumY2 += y2; //计算各个点的y^2的和 sumY2 += y2; //计算各个点的y^2的和
sumX3 += x3; //计算x^3的和 sumX3 += x3; //计算x^3的和
sumY3 += y3; sumY3 += y3;
sumX1Y1 += xy; sumX1Y1 += xy;
sumX1Y2 += x1y2; sumX1Y2 += x1y2;
@ -117,11 +117,11 @@ void FitCircleCenter(vector<Point>& Circle_Data, Point2f& Circle_Center, float&
int RANSAC_FitCircleCenter(vector<Point>& Circle_Data, Point2f& Circle_Center, float& Circle_R, float thresh) int RANSAC_FitCircleCenter(vector<Point>& Circle_Data, Point2f& Circle_Center, float& Circle_R, float thresh)
{ {
// 定义RANSAC迭代次数和最小样本数 // 定义RANSAC迭代次数和最小样本数
int iterations = 1000; int iterations = 1000;
int min_samples = 3; int min_samples = 3;
// 使用RANSAC算法拟合圆形 // 使用RANSAC算法拟合圆形
float best_radius = 0; float best_radius = 0;
Point2f best_center; Point2f best_center;
std::vector<int> is_inlier(Circle_Data.size(), 0); std::vector<int> is_inlier(Circle_Data.size(), 0);
@ -132,7 +132,7 @@ int RANSAC_FitCircleCenter(vector<Point>& Circle_Data, Point2f& Circle_Center, f
while (sample_count < iterations) while (sample_count < iterations)
{ {
// 随机选择最小样本数个点 // 随机选择最小样本数个点
vector<Point> points; vector<Point> points;
for (int j = 0; j < min_samples; j++) for (int j = 0; j < min_samples; j++)
{ {
@ -141,12 +141,12 @@ int RANSAC_FitCircleCenter(vector<Point>& Circle_Data, Point2f& Circle_Center, f
points.push_back(point); points.push_back(point);
} }
// 使用最小二乘法拟合圆形 // 使用最小二乘法拟合圆形
float radius; float radius;
Point2f center; Point2f center;
FitCircleCenter(points, center, radius); FitCircleCenter(points, center, radius);
// 计算所有点与圆之间的距离,以确定内点 // 计算所有点与圆之间的距离,以确定内点
vector<Point2f> inliers; vector<Point2f> inliers;
for (int i = 0; i < Circle_Data.size(); i++) for (int i = 0; i < Circle_Data.size(); i++)
{ {
@ -160,28 +160,28 @@ int RANSAC_FitCircleCenter(vector<Point>& Circle_Data, Point2f& Circle_Center, f
inliers.push_back(point); inliers.push_back(point);
} }
} }
// 更新最佳拟合圆形 // 更新最佳拟合圆形
if (inliers.size() > max_inlier_num) { if (inliers.size() > max_inlier_num) {
max_inlier_num = inliers.size(); max_inlier_num = inliers.size();
is_inlier = is_inlier_tmp; is_inlier = is_inlier_tmp;
best_radius = radius; best_radius = radius;
best_center = center; best_center = center;
} }
//6. 更新迭代的最佳次数 //6. 更新迭代的最佳次数
if (inliers.size() == 0) if (inliers.size() == 0)
{ {
iterations = 1000; iterations = 1000;
} }
else else
{ {
double epsilon = 1.0 - double(inliers.size()) / (double)Circle_Data.size(); //野值点比例 double epsilon = 1.0 - double(inliers.size()) / (double)Circle_Data.size(); //野值点比例
double p = 0.9; //所有样本中存在1个好样本的概率 double p = 0.9; //所有样本中存在1个好样本的概率
double s = 3.0; double s = 3.0;
iterations = int(std::log(1.0 - p) / std::log(1.0 - std::pow((1.0 - epsilon), s))); iterations = int(std::log(1.0 - p) / std::log(1.0 - std::pow((1.0 - epsilon), s)));
} }
sample_count++; sample_count++;
} }
//7. 基于最优的结果所对应的内点做最终拟合 //7. 基于最优的结果所对应的内点做最终拟合
std::vector<cv::Point2f> inliers; std::vector<cv::Point2f> inliers;
inliers.reserve(max_inlier_num); inliers.reserve(max_inlier_num);
for (int i = 0; i < is_inlier.size(); i++) for (int i = 0; i < is_inlier.size(); i++)
@ -297,9 +297,9 @@ int defaultIsoData(int* data)
// { // {
// return dst; // return dst;
// } // }
// //brightness_offset:亮度偏移范围 -255 到 +255 // //brightness_offset:亮度偏移范围 -255 到 +255
// //contrast_factor:对比度因子范围 0.1 到 3.01.0为不变) // //contrast_factor:对比度因子范围 0.1 到 3.01.0为不变)
// //opacity_factor:透明度因子范围 0 到 10为透明1为不透明 // //opacity_factor:透明度因子范围 0 到 10为透明1为不透明
// //
// Mat img8bit; // Mat img8bit;
// src.convertTo(img8bit, CV_8UC1, 0.00390625); // src.convertTo(img8bit, CV_8UC1, 0.00390625);
@ -311,7 +311,7 @@ int defaultIsoData(int* data)
// img_with_opacity.convertTo(img_with_opacity, CV_8UC1); // img_with_opacity.convertTo(img_with_opacity, CV_8UC1);
// //
// Mat img_with_opacity_rgb; // Mat img_with_opacity_rgb;
// cvtColor(img_with_opacity, img_with_opacity_rgb, COLOR_GRAY2BGR); // 将单通道灰度图像转换为三通道RGB图像 // cvtColor(img_with_opacity, img_with_opacity_rgb, COLOR_GRAY2BGR); // 将单通道灰度图像转换为三通道RGB图像
// //
// for (int y = 0; y < pseudoImg.rows; y++) { // for (int y = 0; y < pseudoImg.rows; y++) {
// for (int x = 0; x < pseudoImg.cols; x++) { // for (int x = 0; x < pseudoImg.cols; x++) {
@ -424,30 +424,30 @@ Mat bgr_scale_image(Mat src, float maxVal, float minVal)
//int blendImages(const Mat& src, const Mat& mark, const Mat& dst, double alpha) //int blendImages(const Mat& src, const Mat& mark, const Mat& dst, double alpha)
//{ //{
// // 检查输入图像的类型和大小 // // 检查输入图像的类型和大小
// if (src.type() != CV_16UC1 || mark.type() != CV_8UC3) // if (src.type() != CV_16UC1 || mark.type() != CV_8UC3)
// { // {
// return -1; // 错误处理 // return -1; // 错误处理
// } // }
// //
// // 将 alpha 从 0-100 的范围转换为 0-1 // // 将 alpha 从 0-100 的范围转换为 0-1
// double alpha_normalized = alpha / 100.0; // double alpha_normalized = alpha / 100.0;
// //
// // 将 src 从 16 位转换为 8 位 // // 将 src 从 16 位转换为 8 位
// Mat src8U; // Mat src8U;
// src.convertTo(src8U, CV_8UC1, 1.0 / 256); // 将16位值缩放到0-255范围 // src.convertTo(src8U, CV_8UC1, 1.0 / 256); // 将16位值缩放到0-255范围
// //
// // 将 src8U 转换为彩色图像,以便与 mark 融合 // // 将 src8U 转换为彩色图像,以便与 mark 融合
// Mat srcColor; // Mat srcColor;
// cvtColor(src8U, srcColor, COLOR_GRAY2RGB); // 转换为 BGR 彩色图像 // cvtColor(src8U, srcColor, COLOR_GRAY2RGB); // 转换为 BGR 彩色图像
// //
// // 创建一个输出图像 // // 创建一个输出图像
// Mat blended; // Mat blended;
// //
// // 使用 addWeighted 进行融合 // // 使用 addWeighted 进行融合
// addWeighted(srcColor, 1, mark,alpha_normalized, 0.0, blended); // addWeighted(srcColor, 1, mark,alpha_normalized, 0.0, blended);
// blended.copyTo(dst); // blended.copyTo(dst);
// return 1; // 成功 // return 1; // 成功
//} //}
@ -792,9 +792,9 @@ Mat render_mask_image(Mat src, Mat pseudoImg, int brightness_offset, double cont
{ {
return dst; return dst;
} }
//brightness_offset:亮度偏移范围 -255 到 +255 //brightness_offset:亮度偏移范围 -255 到 +255
//contrast_factor:对比度因子范围 0.1 到 3.01.0为不变) //contrast_factor:对比度因子范围 0.1 到 3.01.0为不变)
//opacity_factor:透明度因子范围 0 到 10为透明1为不透明 //opacity_factor:透明度因子范围 0 到 10为透明1为不透明
Mat img8bit; Mat img8bit;
src.convertTo(img8bit, CV_8UC1, 0.00390625); src.convertTo(img8bit, CV_8UC1, 0.00390625);
@ -806,7 +806,7 @@ Mat render_mask_image(Mat src, Mat pseudoImg, int brightness_offset, double cont
img_with_opacity.convertTo(img_with_opacity, CV_8UC1); img_with_opacity.convertTo(img_with_opacity, CV_8UC1);
Mat img_with_opacity_rgb; Mat img_with_opacity_rgb;
cvtColor(img_with_opacity, img_with_opacity_rgb, COLOR_GRAY2BGR); // 将单通道灰度图像转换为三通道RGB图像 cvtColor(img_with_opacity, img_with_opacity_rgb, COLOR_GRAY2BGR); // 将单通道灰度图像转换为三通道RGB图像
for (int y = 0; y < pseudoImg.rows; y++) { for (int y = 0; y < pseudoImg.rows; y++) {
for (int x = 0; x < pseudoImg.cols; x++) { for (int x = 0; x < pseudoImg.cols; x++) {
@ -1212,31 +1212,28 @@ Mat get_photon_image(Mat src, float sec, float Wcm, float Hcm, float sr)
return dst; return dst;
} }
Mat get_magic_wand_image(Mat src, int x, int y, int th) Mat get_magic_wand_image(Mat src,int x,int y,float max,float min)
{ {
std::cout << "1" << std::endl;
Mat matDst = cv::Mat::zeros(src.size(), CV_8UC1); Mat matDst = cv::Mat::zeros(src.size(), CV_8UC1);
std::cout << "11" << std::endl; cv::Point2i pt(x,y);
cv::Point2i pt(x, y); int w = src.cols;
std::cout << "12" << std::endl; int h = src.rows;
// int nSrcValue = src.at<uchar>(pt.y, pt.x);
int nSrcValue = src.data[pt.y * w + pt.x];
if(nSrcValue < min)
{
return matDst;
}
cv::Point2i ptGrowing; cv::Point2i ptGrowing;
std::cout << "13" << std::endl;
int nGrowLable = 0; int nGrowLable = 0;
int nSrcValue = 0;
int nCurValue = 0; int nCurValue = 0;
int mat_cnt = 0; int mat_cnt = 0;
int DIR[8][2] = { { -1, -1 }, { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 }, { -1, 0 } }; int DIR[8][2] = { { -1, -1 }, { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 }, { -1, 0 } };
std::cout << "14" << std::endl;
std::vector<cv::Point2i> vcGrowPt; std::vector<cv::Point2i> vcGrowPt;
std::cout << "15" << std::endl;
vcGrowPt.push_back(pt); vcGrowPt.push_back(pt);
std::cout << "16" << std::endl; // matDst.at<uchar>(pt.y, pt.x) = 255;
matDst.at<uchar>(pt.y, pt.x) = 255; matDst.data[pt.y * w + pt.x] = 255;
std::cout << "17" << std::endl;
std::cout << "w:" << src.rows << "h:" << src.cols << std::endl;
std::cout << pt.y <<":1:" << pt.x << std::endl;
nSrcValue = src.at<uchar>(pt.y, pt.x);
std::cout << "2" << std::endl;
while (!vcGrowPt.empty()) while (!vcGrowPt.empty())
{ {
pt = vcGrowPt.back(); pt = vcGrowPt.back();
@ -1245,38 +1242,38 @@ Mat get_magic_wand_image(Mat src, int x, int y, int th)
std::vector<cv::Point2i> temp_vcGrowPt; std::vector<cv::Point2i> temp_vcGrowPt;
int temp_vcGrowPt_size = 0; int temp_vcGrowPt_size = 0;
// nSrcValue = src.at<uchar>(pt.y, pt.x); // nSrcValue = src.at<uchar>(pt.y, pt.x);
//分别对八个方向上的点进行生长 //分别对八个方向上的点进行生长
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
{ {
ptGrowing.x = pt.x + DIR[i][0]; ptGrowing.x = pt.x + DIR[i][0];
ptGrowing.y = pt.y + DIR[i][1]; ptGrowing.y = pt.y + DIR[i][1];
//检查是否是边缘点 //检查是否是边缘点
if (ptGrowing.x < 0 || ptGrowing.y < 0 || ptGrowing.x >(src.cols - 1) || (ptGrowing.y > src.rows - 1)) if (ptGrowing.x < 0 || ptGrowing.y < 0 || ptGrowing.x >(src.cols - 1) || (ptGrowing.y > src.rows - 1))
continue; continue;
nGrowLable = matDst.at<uchar>(ptGrowing.y, ptGrowing.x); //当前待生长点的灰度值 // nGrowLable = matDst.at<uchar>(ptGrowing.y, ptGrowing.x);
if (nGrowLable == 0) //如果标记点还没有被生长 nGrowLable = matDst.data[ptGrowing.y * w + ptGrowing.x]; //当前待生长点的灰度值
if (nGrowLable == 0) //如果标记点还没有被生长
{ {
nCurValue = src.at<uchar>(ptGrowing.y, ptGrowing.x); nCurValue = src.data[ptGrowing.y * w + ptGrowing.x];
if (abs(nCurValue - nSrcValue) < th) //在阈值范围内则生长 if (nCurValue >= min) //在阈值范围内则生长
{ {
// matDst.at<uchar>(ptGrowing.y, ptGrowing.x) = 255; // matDst.at<uchar>(ptGrowing.y, ptGrowing.x) = 255;
temp_vcGrowPt_size++; temp_vcGrowPt_size++;
temp_vcGrowPt.push_back(ptGrowing); //将下一个生长点压入栈中 temp_vcGrowPt.push_back(ptGrowing); //将下一个生长点压入栈中
} }
} }
else { else {
temp_vcGrowPt_size++; temp_vcGrowPt_size++;
} }
} }
std::cout << "3" << std::endl; //相邻的生长点不是单向生长,则生长点有效
//相邻的生长点不是单向生长,则生长点有效
if (temp_vcGrowPt_size >= 1) { if (temp_vcGrowPt_size >= 1) {
mat_cnt++; mat_cnt++;
matDst.at<uchar>(pt.y, pt.x) = 255; // matDst.at<uchar>(pt.y, pt.x) = 255;
matDst.data[pt.y * w + pt.x] = 255;
vcGrowPt.insert(vcGrowPt.end(), temp_vcGrowPt.begin(), temp_vcGrowPt.end()); vcGrowPt.insert(vcGrowPt.end(), temp_vcGrowPt.begin(), temp_vcGrowPt.end());
} }
std::cout << "4" << std::endl;
} }
return matDst; return matDst;
} }