C++ opencv line detection

55 篇文章 0 订阅
50 篇文章 1 订阅

对于直线检测有很多种方法,目前,接触的检测精度最高的应该LSD,LSD你可以在github上直接获取源码也可以直接在opencv中调用。其中我调试好的LSD源码可以私信我。

  • ---->There are many methods for line detection, at present, the contact detection accuracy should be the highest LSD, you can directly get the source on github and can also be directly in opencv call.Among them I debugged good LSD source code can private message me.

我采用形态学的方法,通过腐蚀膨胀,设计检测结构元素,进行提取直线,相关代码参考如下:

  • ---->By means of morphology, I designed and detected structural elements through corrosion and expansion to extract the straight lines. The relevant codes are as follows:
//==========================================================================
//==========================================================================
// 用来生成存储横纵线条的图像
int scale_h = 40; // 增加/减少检测到的线条数量//40
// 在水平轴上指定尺寸 size的width应大于图像中的横向笔划
int horizontalsize = srcImageBin.cols / scale_h;

//为了获取横向的表格线,设置腐蚀和膨胀的操作区域为一个比较大的横向直条 //MORPH_RECT
Mat horizontalStructure = getStructuringElement(MORPH_CROSS, Size(horizontalsize, 1));
//先腐蚀后膨胀
erode(srcImageBin, srcImageBin, horizontalStructure, Point(-1, -1));//腐蚀
dilate(srcImageBin, srcImageBin, horizontalStructure, Point(-1, -1));//膨胀
//定义水平直线结构元素,开操作进行水平直线的提取
//Mat kernel = getStructuringElement(MORPH_RECT, Size(horizontalSize, 2), Point(-1, -1));
//morphologyEx(horizontalMat, horizontalMat, MORPH_OPEN, kernel);
//膨胀加强直线
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
dilate(srcImageBin, srcImageBin, kernel);

//    //定义水平直线结构元素,开操作进行水平直线的提取
//    Mat kernel = getStructuringElement(MORPH_RECT, Size(horizontalsize, 2), Point(-1, -1));
//    morphologyEx(srcImageBin, srcImageBin, MORPH_OPEN, kernel);

//    //测试代码
//    //imshow("morphImg", srcImageBin);
//    //膨胀加强直线
//    kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
//    dilate(srcImageBin, srcImageBin, kernel);

cv::imwrite(".//Output//Table_horizontalMat.jpg", srcImageBin);
//==========================================================================
//==========================================================================

你可以对形态学检测的直线进行膨胀加强,通过这个方法可以避免直线的间断。

  • ---->You can expand the lines that you detect morphologically, and by doing so you can avoid discontinuities.

通过对形态学处理后的图像,只包含水平直线的二值化图像,采用HOUGH进行重构处理。

  • ---->After morphological processing, only the binarization image of horizontal line was included in the image, and HOUGH was used to reconstruct the image.

hough的函数介绍可以参看opencv的手册,或者直接看opencv的源码。

  • ---->See the opencv manual for hough's functions, or look directly at the source code for opencv.

对于hough的直线检测代码以及对于短线坐标的处理,你可以参考我的代码,如果我的代码有问题请及时和我联系。

  • ---->For hough's line detection code and the processing of short line coordinates, you can refer to my code. If there is any problem with my code, please contact me in time.
//==========================================================================
//==========================================================================
//霍夫直线检测
vector<Vec4i>lines;
HoughLinesP(srcImageBin, lines, 1, CV_PI / 180, 30, 20.0, 0);
Mat resultImg = srcImageBin.clone();
cvtColor(resultImg, resultImg, CV_GRAY2BGR);
Mat HorizonProjectionMat(srcImageBin.rows, srcImageBin.cols, CV_8UC1, cv::Scalar(0, 0, 0));
vector<int> HoughLinesP_Y;
vector<int> HoughLinesP_Y_OKAY;
for (int i = 0; i < lines.size(); i++)
{
	int x1 = lines[i][0];
	int y1 = lines[i][1];
	int x2 = lines[i][2];
	int y2 = lines[i][3];
	line(HorizonProjectionMat, Point(x1, y1), Point(x2, y2), Scalar(255, 255, 255),1);
}
imwrite(".//Output//HorizonallProjectionMat_table_HoughLinesP.jpg",HorizonProjectionMat);
//==========================================================================
//==========================================================================

标准霍夫线变换

cv2.HoughLines(image, rho, theta, threshold[, lines[, srn[, stn[, min_theta[, max_theta]]]]]) 

参数:image-边缘检测的输出图像,8位,单通道二进制源图像

    rho-距离步长

    theta-角度步长

    threshold-阈值,只有大于该值的点才有可能被当作极大值,即至少有多少条正弦曲线交于一点才被认为是直线

  • ---->Standard hough line transformation
  • ---->Parameter: image- the output image of edge detection, 8-bit, single-channel binary source image
  • ---->Rho - distance step size
  • ---->Theta - Angle step

  • ---->Threshold - threshold value. Only points larger than this value can be considered as maxima. That is, how many sinusoids intersect at a point can be considered as a straight line

统计概率霍夫线变换

cv2.HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]]) 

参数:image-边缘检测的输出图像,该图像为单通道8位二进制图像

     rho-参数极径以像素值为单位的分辨率,这里一般使用 1 像素

     theta-参数极角以弧度为单位的分辨率,这里使用 1度

     threshold-检测一条直线所需最少的曲线交点

     minLineLength-线的最短长度,比这个线短的都会被忽略

     maxLineGap-两条线之间的最大间隔,如果小于此值,这两条线就会被看成一条线。

  • ---->Statistical probability hough line transformation
  • ---->Parameter: image- the output image of edge detection, which is a single-channel 8-bit binary image

  • ---->Rho - the resolution of the parameter radius in pixels, usually 1 pixel

  • ---->Theta - the resolution in radians of the parameter's polar Angle, 1 degree is used here

  • ---->Threshold - the minimum number of intersection points required to detect a straight line

  • ---->MinLineLength - the shortest length of a line. Anything shorter than this line will be ignored

  • ---->MaxLineGap - the maximum spacing between two lines, which are treated as a line if less than this value.

HoughLinesP,效果更好,检测图像中分段的直线(而不是贯穿整个图像的直线)

  • ---->HoughLinesP, for better results, detects the line in the image segment (instead of the line running through the entire image)

​​​I hope I can help you,If you have any questions, please  comment on this blog or send me a private message. I will reply in my free time.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
火焰检测是指通过图像处理技术来检测图像中是否存在火焰。在C++中,可以使用OpenCV库来实现火焰检测。可以采用YOLO4TINY的模型来进行检测,该模型具有移植性好、速度快等优点。以下是实现火焰检测的步骤: ```C++ // 1. 导入OpenCV库 #include <opencv2/opencv.hpp> using namespace cv; int main() { // 2. 读取图像 Mat image = imread("fire.jpg"); // 3. 创建YOLO4TINY模型 dnn::Net net = dnn::readNetFromDarknet("yolov4-tiny.cfg", "yolov4-tiny.weights"); net.setPreferableBackend(dnn::DNN_BACKEND_OPENCV); net.setPreferableTarget(dnn::DNN_TARGET_CPU); // 4. 获取输出层名称 std::vector<String> names; std::ifstream ifs("coco.names"); std::string line; while (std::getline(ifs, line)) names.push_back(line); // 5. 进行目标检测 Mat blob = dnn::blobFromImage(image,1 / 255.0, Size(416, 416), Scalar(), true, false); net.setInput(blob); std::vector<Mat> outs; net.forward(outs, net.getUnconnectedOutLayersNames()); std::vector<int> classIds; std::vector<float> confidences; std::vector<Rect> boxes; for (size_t i = 0; i < outs.size(); ++i) { // 获取每个输出层的信息 float* data = (float*)outs[i].data; for (int j = 0; j < outs[i].rows; ++j, data += outs[i].cols) { Mat scores = outs[i].row(j).colRange(5, outs[i].cols); Point classIdPoint; double confidence; minMaxLoc(scores, 0, &confidence, 0, &classIdPoint); if (confidence > 0.5) { int centerX = (int)(data[0] * image.cols); int centerY = (int)(data[1] * image.rows); int width = (int)(data[2] * image.cols); int height = (int)(data[3] * image.rows); int left = centerX - width / 2; int top = centerY - height / 2; classIds.push_back(classIdPoint.x); confidences.push_back((float)confidence); boxes.push_back(Rect(left, top, width, height)); } } } // 6. 绘制检测结果 std::vector<int> indices; dnn::NMSBoxes(boxes, confidences, 0.5, 0.4, indices); for (size_t i = 0; i < indices.size(); ++i) { int idx = indices[i]; Rect box = boxes[idx]; int classId = classIds[idx]; float confidence = confidences[idx]; Scalar color = Scalar(0, 0, 255); rectangle(image, box, color, 2); String label = format("%s: %.2f", (const char*)names[classId].c_str(), confidence); int baseLine; Size labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine); rectangle(image, Point(box.x, box.y - labelSize.height - baseLine), Point(box.x + labelSize.width, box.y), color, FILLED); putText(image, label, Point(box.x, box.y - baseLine), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 255, 255)); } // 7. 显示检测结果 imshow("Fire Detection", image); waitKey(0); return 0; } ``` 相关问题:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值