孔洞填充
void fillHole(const Mat srcBw, Mat &dstBw)
{
Size m_Size = srcBw.size();
Mat Temp=Mat::zeros(m_Size.height+2,m_Size.width+2,srcBw.type());//延展图像
srcBw.copyTo(Temp(Range(1, m_Size.height + 1), Range(1, m_Size.width + 1)));
cv::floodFill(Temp, Point(0, 0), Scalar(255,255,255));
Mat cutImg;//裁剪延展的图像
Temp(Range(1, m_Size.height + 1), Range(1, m_Size.width + 1)).copyTo(cutImg);
dstBw = srcBw | (~cutImg);
}
fillHole(ThrImg, ThrImg);
https://blog.csdn.net/wangyaninglm/article/details/47701047?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-47701047-blog-128034901.235^v43^pc_blog_bottom_relevance_base5&spm=1001.2101.3001.4242.1&utm_relevant_index=3
转换
16位转8位
cvtColor(OpenImage,OpenImage,COLOR_BGR2GRAY);
字符串转换
std::to_string(i)
//生成随机颜色,用于区分不同连通域
RNG rng(10086);
Mat out;
int number=connectedComponents(OpenImage,out,8,CV_16U);//统计图像连通域的个数
vector<Vec3b>colors;
for(int i=0;i<number;++i){
//使用均匀分布的随机确定颜色
Vec3b vec3=Vec3b(rng.uniform(0,256),rng.uniform(0,256),rng.uniform(0,256));
colors.push_back(vec3);
}
//以不同颜色标记出不同的连通域
Mat result=Mat::zeros(OpenImage.size(),SrcImage_1.type());
int w=result.cols;
int h=result.rows;
for(int row=0;row<h;++row){
for(int col=0;col<w;++col){
int label=out.at<uint16_t>(row,col);
if(label==0){//背景的黑色不改变
continue;
}
result.at<Vec3b>(row,col)=colors[label];
}
}
imshow("标记后的图像",result);
https://blog.csdn.net/qq_33287871/article/details/112691790
图像混合:
float alpha=0.5; Mat MixImage;
addWeighted(ConnectImg, alpha, SrcImage_1, 1 - alpha, 0, MixImage);
中值滤波(去二值化图像毛刺):
medianBlur(ConnectImg,ConnectImg,9);
https://ask.csdn.net/questions/375741
霍夫直线检测
//1、边缘检测
Canny(ConnectImg, CanImg, position, 255, 3);
imshow("CanImg", CanImg);
vector<Vec4i> lines; // 存储检测到的直线
HoughLinesP(CloseImage, lines, 1, CV_PI / 180, 80, 30, 10); // 应用霍夫直线检测算法,输入图像必须是边缘检测后的图像 因为它需要的是边缘信息或者梯度信息来找到线段。
for (size_t i = 0; i < lines.size(); i++)
{
Vec4i l = lines[i];
line(SrcImage_1, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 3, LINE_AA); //直线必须画在三通道的RGB图像中
}
imshow("HoughSrcImage_1", SrcImage_1);
LSD直线检测
方法一:
#include <iostream>
#include <string>
#include "opencv2/core/core.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
//1、边缘检测
Canny(ConnectImg, CanImg, 0, 255, 3);
imshow("CanImg", CanImg);
Ptr<LineSegmentDetector> LS=createLineSegmentDetector(LSD_REFINE_STD);
vector<Vec4f>lines_LSD;
LS->detect(CanImg,lines_LSD);
Mat drawLSDlines(CanImg);
LS->drawSegments(drawLSDlines,lines_LSD);
imshow("LSD",drawLSDlines);
方法二:
Ptr<LineSegmentDetector> detector = createLineSegmentDetector();
vector<Vec4f> lines;
detector->detect(CanImg,
lines);
Mat resultLSD(CanImg.size(),
CV_8UC3,
Scalar(0, 0, 0));
Scalar color(0,0,255);
int thickness = 1;
cout<<"lines.size : "<<lines.size();
for(int i=0; i<lines.size(); i++)
{
Point start(static_cast<int>(lines[i][0]), static_cast<int>(lines[i][1]));
Point end(static_cast<int>(lines[i][2]), static_cast<int>(lines[i][3]));
line(resultLSD, start, end, color, thickness);
}
imshow("resultLSD", resultLSD);
点距离直线筛选(检查直线是否与圆相交)
bool isLineIntersectsCircle(const Vec4i& line, const Point& circleCenter, int circleRadius) {
Point start(line[0], line[1]);
Point end(line[2], line[3]);
// 使用点到直线距离来判断是否相交
double dist = pointToLineDistance(circleCenter, start, end);
if (dist <= circleRadius) {
return true;
}
// 补充:检查圆心是否在直线上(重要!)
double dotProduct = ((end.x - start.x) * (circleCenter.x - start.x) + (end.y - start.y) * (circleCenter.y - start.y));
double squaredLength = (end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y);
if (squaredLength != 0) {
double param = dotProduct / squaredLength;
if (param >= 0 && param <= 1) {
Point closestPoint;
closestPoint.x = start.x + param * (end.x - start.x);
closestPoint.y = start.y + param * (end.y - start.y);
double distanceFromCenter = norm(circleCenter - closestPoint); //计算圆心到最近点的距离
if (distanceFromCenter <= circleRadius) {
return true;
}
}
}
return false;
}
函数调用:
Point circleCenter1(140, 135); // 替换为你的圆心坐标(别忘了你图像缩小了6倍)
Point circleCenter2(690, 72); // 替换为你的圆心坐标
int circleRadius =60;
// 使用 std::vector<int> 来存储与圆相交的第一条直线
std::vector<int> intersectingLineIndices;
for (size_t i = 0; i < extendedLines.size(); ++i) {
if (isLineIntersectsCircle(extendedLines[i], circleCenter1, circleRadius)) {
intersectingLineIndices.push_back(i);
break; // 找到一条后立即退出循环,避免继续查找
}
}
// 检验是否存在相交线
if (!intersectingLineIndices.empty()) {
int index = intersectingLineIndices[0];
line(SrcImage_1, Point(extendedLines[index][0], extendedLines[index][1]),
Point(extendedLines[index][2], extendedLines[index][3]), Scalar(0, 0, 255), 2);
std::cout << "Found intersecting line at index " << index << std::endl;
}
else {
std::cout << "No intersecting line found." << std::endl;
}