Line Detection

本文介绍了图像处理中的线条检测技术,通过特定的卷积核检测不同宽度和方向的线条。线条检测不仅能用于边缘检测,还可以通过连接线段找到完整的线条。文章通过实例展示了如何使用不同宽度的卷积核分析图像中的线条特征,并讨论了在实际图像上的应用,如区分线条与边缘。
摘要由CSDN通过智能技术生成

http://homepages.inf.ed.ac.uk/rbf/HIPR2/linedet.htm

Line Detection


Common Names: Line detection

Brief Description

While edges (i.e. boundaries between regions with relatively distinct graylevels) are by far the most common type of discontinuity in an image, instances of thin lines in an image occur frequently enough that it is useful to have a separate mechanism for detecting them. Here we present a convolution based technique which produces an image description of the thin lines in an input image. Note that the Hough transform can be used to detect lines; however, in that case, the output is a parametric description of the lines in an image.

How It Works

The line detection operator consists of a convolution kernel tuned to detect the presence of lines of a particular width n, at a particular orientation Eqn:eqntheta. Figure 1 shows a collection of four such kernels, which each respond to lines of single pixel width at the particular orientation shown.




Figure 1 Four line detection kernels which respond maximally to horizontal, vertical and oblique (+45 and - 45 degree) single pixel wide lines.

These masks above are tuned for light lines against a dark background, and would give a big negative response to dark lines against a light background. If you are only interested in detecting dark lines against a light background, then you should negate the mask values. Alternatively, you might be interested in either kind of line, in which case, you could take the absolute value of the convolution output. In the discussion and examples below, we will use the kernels above without an absolute value.

If Eqn:eqnldr denotes the response of kernel i, we can apply each of these kernels across an image, and for any particular point, if Eqn:eqnldr2 for all Eqn:eqnldji that point is more likely to contain a line whose orientation (and width) corresponds to that of kernel i. One usually thresholds Eqn:eqnldr to eliminate weak lines corresponding to edges and other features with intensity gradients which have a different scale than the desired line width. In order to find complete lines, one must join together line fragments, e.g., with an edge tracking operator.

Guidelines for Use

To illustrate line detection, we start with the artificial image

art2

which contains thick line segments running horizontally, vertically and obliquely across the image. The result of applying the line detection operator, using the horizontal convolution kernel shown in Figure 1.a, is

art2ldh1

(Note that this gradient image has been normalized for display.) There are two points of interest to note here.

  1. Notice that, because of way that the oblique lines (and some `vertical' ends of the horizontal bars) are represented on a square pixel grid, e.g.
    art2crp1

    shows a zoomed region containing both features, the horizontal line detector responds to more than high spatial intensity horizontal line-like features, e.g.

    art2crp2

  2. On an image such as this one, where the lines to be detected are wider than the kernel (i.e. the image lines are five pixels wide, while the kernel is tuned for a single width pixel), the line detector acts like an edge detector: the edges of the lines are found, rather than the lines themselves.

This latter fact might cause us to naively think that the image which gave rise to

art2ldh1

contained a series of parallel lines rather than single thick ones. However, if we compare this result to that obtained by applying the line detection kernel to an image containing lines of a single pixel width, we find some consistent differences. For example, we can skeletonize the original

art2skl1

(so as to obtain a representation of the original wherein most lines are a single pixel width), apply the horizontal line detector

art2ldh2

and then threshold the result

art2ldh3

If we then threshold the original line detected image at the same pixel value, we obtain the null image

art2ldh4

Thus, the Eqn:eqnldr values corresponding to the true, single pixel lines found in the skeletonized version are stronger than those Eqn:eqnldr values corresponding to edges. Also, if we examine a cropped and zoomed version of the line detected raw image

art2crp3

and the skeletonized line detected image

art2crp4

we see that the single pixel width lines are distinguished by a region of minimal response on either side of the maximal response values coincident with the pixel location of a line. One can use this signature to distinguish lines from edges.

The results of line detecting (and then normalizing) the skeletonized version of this image with single pixel width convolution kernels of different Eqn:eqntheta are

art2ldv2

for a vertical kernel,

art2ldp2

for the oblique 45 degree line, and

art2ldn2

for the oblique 135 degree line. The thresholded versions are

art2ldv1

art2ldp1

and

art2ldn1

respectively. We can add these together to produce a reasonably faithful binary representation of the line locations

art2add1

It is instructive to compare the two operators under more realistic circumstances, e.g. with the natural image

brg2

After converting this to a grayscale image

brg3

and applying the Canny operator, we obtain

brg3can1

Applying the line detector yields

brg3lda1

We can improve this result by using a trick employed by the Canny operator. By smoothing the image before line detecting, we obtain the cleaner result

brg3add2

However, even with this preprocessing, the line detector still gives a poor result compared to the edge detector. This is true because there are few single pixel width lines in this image, and therefore the detector is responding to the other high spatial frequency image features (i.e. edges, thick lines and noise). (Note that in the previous example, the image contained the feature that the kernel was tuned for and therefore we were able to threshold away the weaker kernel response to edges.) We could improve this result by increasing the width of the kernel or geometrically scaling the image.

Interactive Experimentation

You can interactively experiment with this operator by clicking here.

Exercises

  1. Consider the basic image
    rob1

    We can investigate the scale of features in the image by applying line detection kernels of different widths. For example, after convolving with a single pixel horizontal line detecting kernel we discover that only the striped shirt of the bank robber contains single pixel width lines. The normalized result is shown in

    rob1ldh1

    and after thresholding (at a value of 254), we obtain

    rob1ldh2

    a) Perform the same analysis on the image

    hse1

    using different width kernels to extract the different features (e.g. roof, windows, doors, etc.). Threshold your result so that the final images contain a binary description of just the feature of interest. b) Try your kernels on other architectural drawings such as

    hse2

    and

    hse4

  2. Investigate a line detection algorithm which might extract the tail feathers of the peacock in
    pea1

    You will most likely need to apply some smoothing as a first step and you may then want apply several different kernels and add the results together. Compare your final result with an edge detection algorithm, e.g. Roberts cross,SobelCompass and/or Canny edge detector.

References

D. Vernon Machine Vision, Prentice-Hall, 1991, Chap. 5.

R. Gonzalez and R. Woods Digital Image Processing, Addison-Wesley Publishing Company, 1992, pp 415 - 416.


以下代码是什么意思,请逐行解释:import tkinter as tk from tkinter import * import cv2 from PIL import Image, ImageTk import os import numpy as np global last_frame1 # creating global variable last_frame1 = np.zeros((480, 640, 3), dtype=np.uint8) global last_frame2 # creating global variable last_frame2 = np.zeros((480, 640, 3), dtype=np.uint8) global cap1 global cap2 cap1 = cv2.VideoCapture("./movie/video_1.mp4") cap2 = cv2.VideoCapture("./movie/video_1_sol.mp4") def show_vid(): if not cap1.isOpened(): print("cant open the camera1") flag1, frame1 = cap1.read() frame1 = cv2.resize(frame1, (600, 500)) if flag1 is None: print("Major error!") elif flag1: global last_frame1 last_frame1 = frame1.copy() pic = cv2.cvtColor(last_frame1, cv2.COLOR_BGR2RGB) img = Image.fromarray(pic) imgtk = ImageTk.PhotoImage(image=img) lmain.imgtk = imgtk lmain.configure(image=imgtk) lmain.after(10, show_vid) def show_vid2(): if not cap2.isOpened(): print("cant open the camera2") flag2, frame2 = cap2.read() frame2 = cv2.resize(frame2, (600, 500)) if flag2 is None: print("Major error2!") elif flag2: global last_frame2 last_frame2 = frame2.copy() pic2 = cv2.cvtColor(last_frame2, cv2.COLOR_BGR2RGB) img2 = Image.fromarray(pic2) img2tk = ImageTk.PhotoImage(image=img2) lmain2.img2tk = img2tk lmain2.configure(image=img2tk) lmain2.after(10, show_vid2) if __name__ == '__main__': root = tk.Tk() # img = ImageTk.PhotoImage(Image.open("logo.png")) heading = Label(root, text="Lane-Line Detection") # heading.configure(background='#CDCDCD',foreground='#364156') heading.pack() heading2 = Label(root, text="Lane-Line Detection", pady=20, font=('arial', 45, 'bold')) heading2.configure(foreground='#364156') heading2.pack() lmain = tk.Label(master=root) lmain2 = tk.Label(master=root) lmain.pack(side=LEFT) lmain2.pack(side=RIGHT) root.title("Lane-line detection") root.geometry("1250x900+100+10") exitbutton = Button(root, text='Quit', fg="red", command=root.destroy).pack(side=BOTTOM, ) show_vid() show_vid2() root.mainloop() cap.release()
06-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值