簡體   English   中英

Opencv和python-兩行之間的陰影區域

[英]Opencv and python - Shading area between two lines

我有一些有效的代碼,但是性能很差,可以做得更好,所以讓我們看看如何對其進行優化。

我有一幅畫有兩條半垂直線的圖像,想在這兩條線之間的區域着色。 我當前的代碼逐像素迭代,這在python中非常慢。

#Get starting images
shade_image = np.zeros_like(image)
line_image = plot_lines(shade_image, left_line, right_line)
#Choose color
shade_color = [0, 255, 0]
#Iterate through and fill blank image
left_switch = False
right_switch = False
for i in range(0, image.shape[0]):
    left_switch = False
    right_switch = False
    for j in range(0, image.shape[1]):
        if left_switch & right_switch: shade_image[i][j] = shade_color
        #Find left edge of left line
        if (not left_switch) & (not right_switch) & np.any(line_image[i][j] != 0):
            left_switch = True
        #Find right edge of left line
        elif left_switch & (not right_switch) & np.all(line_image[i][j] == 0):
            right_switch = True
        #Find left edge of left line
        elif left_switch & right_switch & np.any(line_image[i][j] != 0):
            break
        #In case of a single line, no shading
        elif left_switch & right_switch & (j == (image.shape[1] - 1)):
             shade_image[i].fill(0)
#Shade lane area
output_image = cv2.addWeighted(image, 1.0, shade_image, 1.0, gamma=0.0)

不漂亮。 我在想可以通過使用line_image中的所有非零並創建遮罩來完成此操作,但是我不知道如何在左右兩點之間填充。 我嘗試使用fillPolygon,但我真的不知道如何將所有非零值轉換為頂點。

如果有幫助,陰影也可以合並線條,這是不准確的。


@Alxeander-非常有幫助! 我快到了,除了現在由於邊界框而存在在凸線之外填充的問題,像這樣: 在此處輸入圖片說明

或者,我放棄了cv2.convexHull並將連接點直接用作多邊形的頂點,並得到以下結果: 在此處輸入圖片說明

它遵循曲率(凸面或凹面),但是由於點的順序,它在左右移動時會翻轉。 我試過使用np.flips(points2,0)但沒有變化。 我會在幾乎更多的地方玩更多游戲。


使用np.flip(points2,0)犯了一個錯誤,可以正常工作! 在此處輸入圖片說明

謝謝您的幫助!

由於您的線是由多項式定義的,這意味着您可以輕松地從中獲取點集。 您有域值x和多項式值y 如果將它們放入點數組

points = np.array([[[x1, y1]], ..., [[xn, yn]]])

然后可以將這些點傳遞到OpenCV函數cv2.fillPoly()cv2.drawContours()以填充區域。

請注意,多項式可以輕松地在圖像范圍之外定義線條。 為了繪制輪廓或多邊形,您應該使用封閉的形狀,這樣可以更輕松地將多余的點切出您的域。

這是一個完整的示例,它基於兩個多項式定義一個區域並填充該區域:

import numpy as np 
import cv2

img = cv2.imread('img1.png')
h, w = img.shape[:2]

x = np.arange(w)
polynomial1 = lambda x: x**2/800
polynomial2 = lambda x: x+200
y1 = polynomial1(x)
y2 = polynomial2(x)

points1 = np.array([[[xi, yi]] for xi, yi in zip(x, y1) if (0<=xi<w and 0<=yi<h)]).astype(np.int32)
points2 = np.array([[[xi, yi]] for xi, yi in zip(x, y2) if (0<=xi<w and 0<=yi<h)]).astype(np.int32)
points2 = np.flipud(points2)
points = np.concatenate((points1, points2))

polynomialgon = img.copy()
cv2.fillPoly(polynomialgon, [points], color=[255,255,255])
cv2.imshow('Polygon defined by two polynomials', polynomialgon)
cv2.waitKey(0)

導致:

由兩個多項式定義的填充多邊形

請注意, flipud用來使點從直線的端點沿順時針方向移動。 否則,在polynomial1結束的地方,線會上升到polynomial2開始之處,因此我們要回溯並跨越該區域。 只要沿順時針方向或逆時針方向跟蹤線的端點,線的行為就無關緊要。

亞歷山大將我引向正確的方向,我只需要調整它以處理凸線:

import numpy as np 
import cv2

img = cv2.imread('img1.png')
h, w = img.shape[:2]

x = np.arange(w)
polynomial1 = lambda x: x**2/800
polynomial2 = lambda x: x+200
y1 = polynomial1(x)
y2 = polynomial2(x)

points1 = np.array([[[xi, yi]] for xi, yi in zip(x, y1) if (0<=xi<w and 0<=yi<h)]).astype(np.int32)
points2 = np.array([[[xi, yi]] for xi, yi in zip(x, y2) if (0<=xi<w and 0<=yi<h)]).astype(np.int32)
points = np.concatenate(points1, np.flip(points2, 0))

polynomialgon = img.copy()
cv2.fillPoly(polynomialgon, [points], color=[255,255,255])
cv2.imshow('Polygon defined by two polynomials', polynomialgon)
cv2.waitKey(0)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM