激光条纹中心线提取算法总结和复现

2023-10-30

滤波、分割等预处理过程省略。
输入图像为灰度图,激光条纹水平走向。
在这里插入图片描述

几何中心法

检测出光条边界 l、h 后,把两边界的中间线(l + h)/2作为激光条纹的中心线。

#include <iostream>
#include <opencv2/opencv.hpp>


int main(int argc, char** argv)
{
	cv::Mat src_img = cv::imread("70.bmp", 0);
	cv::Mat dst_img = src_img.clone();
	cv::cvtColor(dst_img, dst_img, cv::COLOR_GRAY2RGB);

	uchar *p = src_img.data;
	std::vector<cv::Point> pts;

	for (size_t i = 0; i < src_img.cols; ++i)
	{
		int y_min = INT_MIN, y_max = INT_MAX;

		for (size_t j = 0; j < src_img.rows; ++j)
		{
			if (*(p + i + src_img.cols * j) != 0)
			{
				y_min = j;
				break;
			}
		}

		for (size_t j = src_img.rows - 1; j > 0; --j)
		{
			if (*(p + i + src_img.cols * j) != 0)
			{
				y_max = j;
				break;
			}
		}

		if (y_min >= 0 && y_max < src_img.rows && y_min < y_max)
		{
			pts.push_back(cv::Point(i, (y_min + y_max) / 2));
		}
	}

	for (size_t i = 0; i < pts.size(); ++i)
	{
		cv::circle(dst_img, cv::Point(round(pts[i].x), round(pts[i].y)), 0.5, cv::Scalar(0, 0, 255), -1); 
	}
	cv::imwrite("70.1.bmp", dst_img);

	system("pause");
	return EXIT_SUCCESS;
}

极值法

极值法是将激光条纹横截面上灰度值最大点作为激光条纹的中心。

#include <iostream>
#include <opencv2/opencv.hpp>


int main(int argc, char** argv)
{
	cv::Mat src_img = cv::imread("70.bmp", 0);
	cv::Mat dst_img = src_img.clone();
	cv::cvtColor(dst_img, dst_img, cv::COLOR_GRAY2RGB);

	uchar *p = src_img.data;
	std::vector<cv::Point> pts;

	for (size_t i = 0; i < src_img.cols; ++i)
	{
		int col_scalar_max = 0;
		int y = INT_MIN;

		for (size_t j = 0; j < src_img.rows; ++j)
		{
			if (*(p + i + src_img.cols * j) > col_scalar_max)
			{
				col_scalar_max = *(p + i + src_img.cols * j);
				y = j;
			}
		}

		pts.push_back(cv::Point(i, y));
	}

	for (size_t i = 0; i < pts.size(); ++i)
	{
		cv::circle(dst_img, cv::Point(round(pts[i].x), round(pts[i].y)), 0.5, cv::Scalar(0, 0, 255), -1);
	}
	cv::imwrite("70.2.bmp", dst_img);

	system("pause");
	return EXIT_SUCCESS;
}

细化法

骨架细化法是重复地剥掉二值图像的边界像素,在剥离的过程中必须保持目标的连通性,直到得到图像的骨架。
具体原理介绍可见Zhang-Suen 图像骨架提取算法的原理和OpenCV实现

#include <iostream>
#include <opencv2/opencv.hpp>


int main(int argc, char** argv)
{
	cv::Mat src_img = cv::imread("70.bmp", 0);
	cv::Mat dst_img = src_img.clone();
	cv::cvtColor(dst_img, dst_img, cv::COLOR_GRAY2RGB);

	//zhang细化算法(中轴变换法)
	cv::Mat copy_img = src_img.clone();

	while (1)
	{
		bool stop = false;
		//step1
		for (int i = 1; i < src_img.cols - 1; i++)
			for (int j = 0; j < src_img.rows; j++)
			{
				if (src_img.at<uchar>(j, i)>0)
				{
					int p1 = int(src_img.at<uchar>(j, i))>0 ? 1 : 0;
					int p2 = int(src_img.at<uchar>(j - 1, i))>0 ? 1 : 0;
					int p3 = int(src_img.at<uchar>(j - 1, i + 1))>0 ? 1 : 0;
					int p4 = int(src_img.at<uchar>(j, i + 1))>0 ? 1 : 0;
					int p5 = int(src_img.at<uchar>(j + 1, i + 1))>0 ? 1 : 0;
					int p6 = int(src_img.at<uchar>(j + 1, i))>0 ? 1 : 0;
					int p7 = int(src_img.at<uchar>(j + 1, i - 1))>0 ? 1 : 0;
					int p8 = int(src_img.at<uchar>(j, i - 1))>0 ? 1 : 0;
					int p9 = int(src_img.at<uchar>(j - 1, i - 1))>0 ? 1 : 0;
					int np1 = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
					int sp2 = (p2 == 0 && p3 == 1) ? 1 : 0;
					int sp3 = (p3 == 0 && p4 == 1) ? 1 : 0;
					int sp4 = (p4 == 0 && p5 == 1) ? 1 : 0;
					int sp5 = (p5 == 0 && p6 == 1) ? 1 : 0;
					int sp6 = (p6 == 0 && p7 == 1) ? 1 : 0;
					int sp7 = (p7 == 0 && p8 == 1) ? 1 : 0;
					int sp8 = (p8 == 0 && p9 == 1) ? 1 : 0;
					int sp9 = (p9 == 0 && p2 == 1) ? 1 : 0;
					int sp1 = sp2 + sp3 + sp4 + sp5 + sp6 + sp7 + sp8 + sp9;

					if (np1 >= 2 && np1 <= 6 && sp1 == 1 && ((p2*p4*p6) == 0) && ((p4*p6*p8) == 0))
					{
						stop = true;
						copy_img.at<uchar>(j, i) = 0;
					}
				}
			}
		//step2
		for (int i = 1; i < copy_img.cols - 1; i++)
		{
			for (int j = 0; j < src_img.rows; j++)
			{
				if (src_img.at<uchar>(j, i)>0)
				{
					int p2 = int(src_img.at<uchar>(j - 1, i))>0 ? 1 : 0;
					int p3 = int(src_img.at<uchar>(j - 1, i + 1)) > 0 ? 1 : 0;
					int p4 = int(src_img.at<uchar>(j, i + 1)) > 0 ? 1 : 0;
					int p5 = int(src_img.at<uchar>(j + 1, i + 1)) > 0 ? 1 : 0;
					int p6 = int(src_img.at<uchar>(j + 1, i)) > 0 ? 1 : 0;
					int p7 = int(src_img.at<uchar>(j + 1, i - 1)) > 0 ? 1 : 0;
					int p8 = int(src_img.at<uchar>(j, i - 1)) > 0 ? 1 : 0;
					int p9 = int(src_img.at<uchar>(j - 1, i - 1)) > 0 ? 1 : 0;
					int np1 = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
					int sp2 = (p2 == 0 && p3 == 1) ? 1 : 0;
					int sp3 = (p3 == 0 && p4 == 1) ? 1 : 0;
					int sp4 = (p4 == 0 && p5 == 1) ? 1 : 0;
					int sp5 = (p5 == 0 && p6 == 1) ? 1 : 0;
					int sp6 = (p6 == 0 && p7 == 1) ? 1 : 0;
					int sp7 = (p7 == 0 && p8 == 1) ? 1 : 0;
					int sp8 = (p8 == 0 && p9 == 1) ? 1 : 0;
					int sp9 = (p9 == 0 && p2 == 1) ? 1 : 0;
					int sp1 = sp2 + sp3 + sp4 + sp5 + sp6 + sp7 + sp8 + sp9;
					if (np1 >= 2 && np1 <= 6 && sp1 == 1 && (p2*p4*p8) == 0 && (p2*p6*p8) == 0)
					{
						stop = true;
						copy_img.at<uchar>(j, i) = 0;
					}
				}
			}
		}

		copy_img.copyTo(src_img);
		if (!stop)
		{
			break;
		}
	}	

	uchar *p = copy_img.data;
	std::vector<cv::Point> pts;

	for (int i = 0; i < copy_img.cols; i++)
		for (int j = 0; j < copy_img.rows; j++)
			if (*(p + i + src_img.cols * j) != 0)
				pts.push_back(cv::Point(i, j));

	for (size_t i = 0; i < pts.size(); ++i)
	{
		cv::circle(dst_img, cv::Point(round(pts[i].x), round(pts[i].y)), 0.5, cv::Scalar(0, 0, 255), -1);
	}
	cv::imwrite("70.3.bmp", dst_img);

	system("pause");
	return EXIT_SUCCESS;
}

灰度重心法

灰度重心法就是对图像中的每一列(行)提取灰度重心作为激光条纹的中心位置。若某行的非零区间为[p,q],则该行的灰度重心位置为:
在这里插入图片描述

式中,I i 是第 i 个像素点的灰度值。

#include <iostream>
#include <opencv2/opencv.hpp>


int main(int argc, char** argv)
{
	cv::Mat src_img = cv::imread("70.bmp", 0);
	cv::Mat dst_img = src_img.clone();
	cv::cvtColor(dst_img, dst_img, cv::COLOR_GRAY2RGB);

	uchar *p = src_img.data;
	std::vector<cv::Point2f> pts;

	for (size_t i = 0; i < src_img.cols; ++i)
	{
		int sum = 0; 
		float y = 0; 

		for (size_t j = 0; j < src_img.rows; ++j)
		{
			int s = *(p + i + src_img.cols * j);
			if (s)
			{
				sum += s;
				y += j*s;
			}
		}
		if (sum)
		{
			y /= sum;
			pts.push_back(cv::Point2f(i, y));
		}
	}

	for (size_t i = 0; i < pts.size(); ++i)
	{
		cv::circle(dst_img, cv::Point(round(pts[i].x), round(pts[i].y)), 0.5, cv::Scalar(0, 0, 255), -1);
	}
	cv::imwrite("70.4.bmp", dst_img);

	system("pause");
	return EXIT_SUCCESS;
}

法向质心法

在这里插入图片描述

#include <iostream>
#include <opencv2/opencv.hpp>


//亚像素灰度值计算
float ijpixel(float x, float y, cv::Mat& img)
{
	int x_0 = int(x);
	int x_1 = int(x + 1);
	int y_0 = int(y);
	int y_1 = int(y + 1);
	int px_0y_0 = int(img.at<uchar>(y_0, x_0));
	int px_0y_1 = int(img.at<uchar>(y_1, x_0));
	int px_1y_0 = int(img.at<uchar>(y_0, x_1));
	int px_1y_1 = int(img.at<uchar>(y_1, x_1));
	float x_y0 = px_0y_0 + (x - float(x_0))*(px_1y_0 - px_0y_0);
	float x_y1 = px_0y_1 + (x - float(x_0))*(px_1y_1 - px_0y_1);
	float x_y = x_y0 + (y - float(y_0))*(x_y1 - x_y0);
	return x_y;
}

int main(int argc, char** argv)
{
	cv::Mat src_img = cv::imread("70.bmp", 0);
	cv::Mat dst_img = src_img.clone();
	cv::cvtColor(dst_img, dst_img, cv::COLOR_GRAY2RGB);

	uchar *p = src_img.data;
	std::vector<cv::Point2f> pts;

	//灰度重心法//
	for (size_t i = 0; i < src_img.cols; ++i)
	{
		int sum = 0;
		float y = 0;

		for (size_t j = 0; j < src_img.rows; ++j)
		{
			int s = *(p + i + src_img.cols * j);
			if (s)
			{
				sum += s;
				y += j*s;
			}
		}
		if (sum)
		{
			y /= sum;
			pts.push_back(cv::Point2f(i, y));
		}
	}

	//法向迭代质心法//
	int iter = 0;
	int max_iter = 10;
	float distance = 0;
	float thre_distance = 0.05;
	std::vector<cv::Point2f> pts_new = pts;

	do
	{
		int pts_tmp_size = 5;
		assert((pts_tmp_size - 1) % 2 == 0);

		for (size_t i = (pts_tmp_size - 1) % 2; i < pts.size() - (pts_tmp_size - 1) % 2; ++i)
		{
			std::vector<cv::Point2f> pts_tmp;
			for (size_t j = 0; j < pts_tmp_size; ++j)
			{
				pts_tmp.push_back(pts[i + j - (pts_tmp_size - 1) % 2]);
			}

			cv::Vec4f line_para;
			cv::fitLine(pts_tmp, line_para, cv::DIST_L2, 0, 1e-2, 1e-2);	//最小二乘拟合直线方程系数
			float k = line_para[1] / line_para[0];
			float sin_theta =  1 / sqrt(k * k + 1);
			float cos_theta =  - k / sqrt(k * k + 1);

			float sum = ijpixel(pts[i].x, pts[i].y, src_img);
			float sumx = ijpixel(pts[i].x, pts[i].y, src_img)* pts[i].x;
			float sumy = ijpixel(pts[i].x, pts[i].y, src_img)* pts[i].y;

			int range = 10;
			for (size_t j = 1; j < range; ++j)
			{
				float x_cor_left = pts[i].x - j*cos_theta;
				float y_cor_left = pts[i].y - j*sin_theta;
				float x_cor_right = pts[i].x + j*cos_theta;
				float y_cor_right = pts[i].y + j*sin_theta;

				if (x_cor_left >= 0 && x_cor_left<src_img.cols && y_cor_left >= 0 && y_cor_left<src_img.rows &&
					x_cor_right >= 0 && x_cor_right<src_img.cols && y_cor_right >= 0 && y_cor_right< src_img.rows)
				{
					if (ijpixel(x_cor_left, y_cor_left, src_img) || ijpixel(x_cor_right, y_cor_right, src_img))
					{
						sum += ijpixel(x_cor_left, y_cor_left, src_img) + ijpixel(x_cor_right, y_cor_right, src_img);
						sumx += ijpixel(x_cor_left, y_cor_left, src_img)*x_cor_left + ijpixel(x_cor_right, y_cor_right, src_img)*x_cor_right;
						sumy += ijpixel(x_cor_left, y_cor_left, src_img)*y_cor_left + ijpixel(x_cor_right, y_cor_right, src_img)*y_cor_right;
					}
				}
			}

			pts_new[i].x = (float)sumx / sum;
			pts_new[i].y = (float)sumy / sum;
		}

		distance = 0;
		for (int i = 0; i < pts.size(); i++)
		{
			distance += pow(pts_new[i].x - pts[i].x, 2) + pow(pts_new[i].y - pts[i].y, 2);
		}
		distance = sqrt(distance/ pts.size());
		iter++;
		std::cout << iter << "\t" << distance << std::endl;

		pts = pts_new;

	} while (iter < max_iter && distance > thre_distance);

	for (size_t i = 0; i < pts.size(); ++i)
	{
		cv::circle(dst_img, cv::Point(round(pts[i].x), round(pts[i].y)), 0.5, cv::Scalar(0, 0, 255), -1);
	}
	cv::imwrite("70.5.bmp", dst_img);

	system("pause");
	return EXIT_SUCCESS;
}

Steger算法

在这里插入图片描述

#include <iostream>
#include <opencv2/opencv.hpp>


int main(int argc, char** argv)
{
	cv::Mat src_img = cv::imread("14.bmp", 0);
	cv::Mat dst_img = src_img.clone();
	cv::cvtColor(dst_img, dst_img, cv::COLOR_GRAY2RGB);

	std::vector<cv::Point2f> pts;

	//src_img.convertTo(src_img, CV_32FC1);
	cv::GaussianBlur(src_img, src_img, cv::Size(0, 0), 6, 6);

	//一阶偏导数
	cv::Mat m1, m2;
	m1 = (cv::Mat_<float>(1, 3) << 1, 0, -1);  //x偏导
	m2 = (cv::Mat_<float>(3, 1) << 1, 0, -1);  //y偏导

	cv::Mat dx, dy;
	cv::filter2D(src_img, dx, CV_32FC1, m1); //卷积
	cv::filter2D(src_img, dy, CV_32FC1, m2);

	//二阶偏导数
	cv::Mat m3, m4, m5;
	m3 = (cv::Mat_<float>(1, 3) << 1, -2, 1);   //二阶x偏导
	m4 = (cv::Mat_<float>(3, 1) << 1, -2, 1);   //二阶y偏导
	m5 = (cv::Mat_<float>(2, 2) << 1, -1, -1, 1);   //二阶xy偏导

	cv::Mat dxx, dyy, dxy;
	cv::filter2D(src_img, dxx, CV_32FC1, m3);
	cv::filter2D(src_img, dyy, CV_32FC1, m4);
	cv::filter2D(src_img, dxy, CV_32FC1, m5);

	//hessian矩阵
	for (size_t i = 0; i < src_img.cols; ++i)
	{
		for (size_t j = 0; j < src_img.rows; ++j)
		{
			if (src_img.at<uchar>(j, i) > 50)
			{
				cv::Mat hessian(2, 2, CV_32FC1);
				hessian.at<float>(0, 0) = dxx.at<float>(j, i);
				hessian.at<float>(0, 1) = dxy.at<float>(j, i);
				hessian.at<float>(1, 0) = dxy.at<float>(j, i);
				hessian.at<float>(1, 1) = dyy.at<float>(j, i);

				cv::Mat eValue, eVectors;
				cv::eigen(hessian, eValue, eVectors); //求特征值与特征向量

				double nx, ny;
				if (fabs(eValue.at<float>(0, 0)) >= fabs(eValue.at<float>(1, 0)))  //求特征值最大时对应的特征向量
				{
					nx = eVectors.at<float>(0, 0);
					ny = eVectors.at<float>(0, 1);
				}
				else
				{
					nx = eVectors.at<float>(1, 0);
					ny = eVectors.at<float>(1, 1);
				}

				double t = -(nx*dx.at<float>(j, i) + ny*dy.at<float>(j, i)) /
					(nx*nx*dxx.at<float>(j, i) + 2 * nx*ny*dxy.at<float>(j, i) + ny*ny*dyy.at<float>(j, i));

				if (fabs(t*nx) <= 0.5 && fabs(t*ny) <= 0.5)
				{
					pts.push_back(cv::Point2f(i + t*nx, j + t*ny));
				}
			}
		}
	}

	for (size_t i = 0; i < pts.size(); ++i)
	{
		cv::circle(dst_img, cv::Point(round(pts[i].x), round(pts[i].y)), 0.5, cv::Scalar(0, 0, 255), -1);
	}
	cv::imwrite("70.6.bmp", dst_img);

	system("pause");
	return EXIT_SUCCESS;
}

后续文章:中心线提取–GPU加速

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

激光条纹中心线提取算法总结和复现 的相关文章

  • 获取 TextBox 中的文本行数

    我试图通过标签显示文本框中的文本行数 但是 问题是如果最后一行为空 标签必须显示没有空行的行号 例如 如果它们有 5 行 最后一行为空 则标签应将行数显示为 4 Thanks private void txt CurrentVinFilte
  • 在 opencv 中一次性将旋转和平移结合起来

    我有一段用于旋转和平移图像的代码 Point2f pt 0 in rows double angle atan trans c trans b 180 M PI Mat r getRotationMatrix2D pt angle 1 0
  • 显示 div 内的用户名列表

    我是 jQuery 新手 在我的项目中 我创建了一个类User其中代码如下所示 static ConcurrentDictionary
  • 读取大文件并制作字典

    我有一个大文件 我需要读取它并从中制作字典 我希望这一切能够尽可能快 然而我的Python代码太慢了 这是一个显示问题的最小示例 首先制作一些假数据 paste lt seq 20000000 lt seq 2 20000001 gt la
  • C# - Visual Studio 中的 System.OutOfMemoryException

    我遇到问题 当我右键单击 Visual Studio 中的主窗体并转到 视图设计器 时 出现错误 它说 引发了 System OutOfMemoryException 类型的异常 堆栈跟踪 at System Reflection Asse
  • 在异步请求中使用超时回调

    我之前问过这个问题 但我将用提出的解决方案来完成这个问题 并提出另一个问题 我正在使用这个类来进行异步网络请求 http msdn microsoft com en us library system net webrequest aspx
  • std::bind2nd 和 std::bind 与二维数组和结构数组

    我知道 C 有 lambda 并且 std bind1st std bind2nd 和 std bind 已弃用 然而 从C 的基础开始 我们可以更好地理解新特性 所以 我从这个非常简单的代码开始 使用int 数组s 第一个例子 与std
  • 如何部署包含第三方 DLL 文件的 C# 应用程序?

    首先 我对部署了解不多 我希望我的问题有意义 我需要将 C 应用程序安装 部署到多个桌面 它需要一个第三方 DLL 文件 一个 C 库 lpsolve55 dll 对于那些感兴趣的人 它是一个免费的 MIP LP 求解器 请参阅 lpsol
  • C语言中没有循环可以打印数组吗?

    例如 在Python中 如果我们将一个列表作为数组 它会直接用一行代码打印整个数组 有什么办法可以用C语言实现同样的事情吗 简短回答 No 对表格上几乎所有问题的简短回答 用 C 语言做 X 工作能像用 Python 一样简单吗 No 长答
  • PartialView Action 正在调用自身

    我有 MVC 应用程序 它用于从主视图 ProductMaster 将 ProductAreaGrid 列表显示为 PartialView 并且它将在局部视图内将 CreateProductArea 作为 PartialView 我的 Gr
  • 从 Golang 调用 C 函数

    我想在 Golang 中编写控制器逻辑并处理 json 和数据库 同时在 C 中使用我的数学处理模型 在我看来 调用 C 函数的开销必须尽可能低 就像设置寄存器 rcx rdx rsi rdi 一样 执行一些操作fastcall 并获取 r
  • += 运算符在 C++ 中是如何实现的?

    这是我一直在思考的一个问题 但从未找到任何资源来说明这个问题的答案 事实上它不仅是为了 也适用于它的兄弟姐妹 即 等等 当然不是 考虑这个例子 int a 5 a 4 this will make a 9 现在考虑等效表达式 a a 4 T
  • 文件加密与解密问题

    我一直在尝试在 VC Express 2010 中加密和解密文件 我见过的所有教程和文档都需要两个FileStreams 来加密文件 一个用于读取未加密的版本 另一个用于加密 当我实际编写代码时 它不断抛出错误 告诉我它无法打开该文件 因为
  • 如何解决文件被另一个进程使用的问题?

    我一直在 VS NET 2010 中调试 没有任何问题 但现在无法建造 我收到错误 Unable to copy file filename to bin Debug filename The process cannot access t
  • 这些工作队列标志意味着什么?

    在研究工作队列时 我遇到了内核中定义的工作队列标志和常量 我有以下我无法理解的疑问 这里的排水和救援到底是什么意思 WQ DRAINING 1 lt lt 6 internal workqueue is draining WQ RESCUE
  • 在 C# 窗口应用程序中运行 C/C++ 控制台应用程序?

    现在 我想开发一个简单的应用程序 因此我决定最快的编码方式是 C NET 但现在 我很难实现我需要的功能之一 我想做的是在 C 应用程序的窗口内运行 C C 控制台应用程序 就像在虚幻前端中一样 添加一点通信方式 以便我可以为控制台应用程序
  • 检查另一种形式的线程是否仍在运行

    我有一个涉及两个窗体的 Windows 窗体应用程序 子表单用于将数据导出到 CSV 文件 并使用后台工作者写入文件 当这种情况发生时 我隐藏了表格 当后台工作程序运行时 父窗体仍然处于活动状态 因此即使后台工作程序正在写入文件 用户也可以
  • Web API 2.0 使用 pascalcase 模型接收驼峰式命名的 JSON 数据

    我正在尝试对我的 Web API 进行 PUT 调用 我在 WebApiConfig cs 中设置了以下内容 以处理以驼峰形式将数据发送回我的 Web 项目 config Formatters JsonFormatter Serialize
  • boost::spirit::qi::语法和可变参数模板

    我在使用可变参数模板定义语法时面临一个问题 我首先定义一些包含在某些结构中的简单语法 例如纬度 经度 如下所示 include
  • 是否可以检测流是否已被客户端关闭?

    简要介绍一下情况 我有一项服务可以通过套接字接收信息并发送回复 连接不安全 我想设置另一个可以为这些连接提供 TLS 的服务 这个新服务将提供单个端口并根据提供的客户端证书分发连接 我不想使用 stunnel 有几个原因 其中之一是每个接收

随机推荐

  • springboot配置json数据序列化工具类

    一 概述 public class FastJsonUtils private static final SerializeConfig config static config new SerializeConfig config put
  • .vcxproj : error : 文件 E:\work\ImageManageSys\images\boat.png 包含在 None 和 None 项组中。项目项不允许这样做,它只能属于一个项

    Qt系列文章目录 提示 这里可以添加系列文章的所有文章的目录 目录需要自己手动添加 例如 第一章 Python 机器学习入门之pandas的使用 文章目录 Qt系列文章目录 前言 一 问题原因 二 解决方法 前言 使用visual stdi
  • android自定义弹出框样式实现

    前言 做项目时 感觉android自带的弹出框样式比较丑 很多应用都是自己做的弹出框 这里也试着自己做了一个 废话不说先上图片 实现机制 1 先自定义一个弹出框的样式 2 自己实现CustomDialog类 继承自Dialog 实现里面方法
  • Java多线程中join方法的理解

    thread Join把指定的线程加入到当前线程 可以将两个交替执行的线程合并为顺序执行的线程 比如在线程B中调用了线程A的Join 方法 直到线程A执行完毕后 才会继续执行线程B t join 使调用线程 t 在此之前执行完毕 t joi
  • 布尔盲注之sqlmap爆破

    布尔盲注之sqlmap爆破 好久没有更新了 语句也忘的差不多了 作为菜鸟的我也是终于弄懂了这道题 以及部分语句的意思 我将用尽可能详细且易理解的语言来表达 sqlmap爆破 首先你得下载sqlmap csdn中刚好有 注入语句 python
  • 图片像素、英寸、厘米之间的单位换算

    转自 http hi baidu com cjg501 blog item f040fc0898d5379f0b7b8244 html 今天朋友用photoshop处理图片时要把图片保存指定的大小 但她只对厘米要形像感 可是在软件里保存的图
  • Maven+Idea打jar包个人总结

    Maven Idea打jar包个人总结 文章目录 Maven Idea打jar包个人总结 1 前言 2 安装配置JDK 3 Maven安装和配置 3 1 下载安装maven 3 2 配置环境变量 3 3 修改maven配置文件并创建本地仓库
  • BigDecimal除法向上取整,保留 1 为小数(Java、MySQL各自写法)

    SQL写法 CEILING SUM hdd SEND OUT QTY hsl DEMAND QTY 1000 10 EXECUTE RATE Java写法 updateData getExecuteQty divide soLineQtyM
  • 阿里云实践 - HTML5断点播放m3u8视频(videojs)

    场景 HTML5页面需要通过
  • EMC问题之RE实验最优解

    EMC问题之RE实验最优解 RE实验中 最关键的可能也是最难的就是找到干扰源 进而确定是传导辐射还是空间辐射 选择对应的是一定要加屏蔽罩 哪怕环路面积很小 辐射能量还是很强 还是仅仅依靠滤波等就能解决问题 实验现象 在160MHz 80MH
  • shell中如何进行一段代码的注释

    在shell编程中 我们常常需要把一些语句注释掉 让它不执行 对单号或者少数几行shell脚本来说 在每行前面增加 符号就可以达到目的了 代码如下 cp a txt b txt mkdir p 1 2 4 2 4 6 echo ok 但如果
  • ARP欺骗和DNS劫持以及Wireshark分析

    一 实验目的 利用ettercap进行中间人攻击之ARP欺骗和DNS劫持 用Wireshark分析相关特征数据 提高对ettercap Wireshark的熟练度 同时也对中间人攻击有更加深入的认识 二 实验原理 常见的ARP欺骗方式有两种
  • 使用conda时出现Solving environment: failed with initial frozen solve. Retrying with flexible solve错误

    使用conda安装pytorch 出现了各种各样的错误 尝试了网上各种办法 最后我是这么解决的 首先添加镜像源 在终端运行以下代码 conda config add channels https mirrors tuna tsinghua
  • JDBC(数据库连接)

    JDBC 简介 什么是 JDBC JDBC 指 Java 数据库连接 是一种标准Java应用编程接口 JAVA API 用来连接 Java 编程语言和广泛的数据库 JDBC API 库包含下面提到的每个任务 都是与数据库相关的常用用法 制作
  • 学习开源项目NewBeeMall新蜂商城(1) - 初步了解与运行NewBeeMall

    文章目录 0 前言 1 NewBeeMall 新蜂商城简介 2 NewBeeMall项目配置与运行 2 1 配置MySQL数据库 2 2 配置图片资源 2 3 运行NewBeeMAll 3 NewBeeMall相关技术栈 3 1 项目原版技
  • 关于++与+=

    今天在模仿别人做购物车网页 本想用jquey的text 获取一件物品的数量 如 1 由于忽略了text 获取的是字符串 于是用了 1运算符 发现字符串也能用 输出为 11 看了模仿的网站发现他并不需要用到parseInt 函数来将字符串变为
  • 454. 4Sum II 解题记录

    题目描述 Given four lists A B C D of integer values compute how many tuples i j k l there are such that A i B j C k D l is z
  • MOSFET 导通条件

    MOSFET管是FET的一种 可以被制造为增强型或者耗尽型 P沟道或N沟道共四种类型 但实际应用的只有增强型的N沟道MOS管和增强型的P沟道MOS管 实际应用中 NMOS居多 如何分辨三个极 D极单独位于一边 而G极是第4PIN 剩下的3个
  • 支持IDE最新版!新一代报表工具FastReport VCL v6.7更新详情

    FastReport VCL是用于Delphi C Builder RAD Studio和Lazarus的报告和文档创建VCL库 它提供了可视化模板设计器 可以访问最受欢迎的数据源 报告引擎 预览 将过滤器导出为30多种格式 并可以部署到云
  • 激光条纹中心线提取算法总结和复现

    滤波 分割等预处理过程省略 输入图像为灰度图 激光条纹水平走向 目录 几何中心法 极值法 细化法 灰度重心法 法向质心法 Steger算法 几何中心法 检测出光条边界 l h 后 把两边界的中间线 l h 2作为激光条纹的中心线 inclu