gpt4 book ai didi

python-3.x - OpenCV-检测不包括阴影的对象

转载 作者:行者123 更新时间:2023-12-02 16:12:32 27 4
gpt4 key购买 nike

我正在开发一种从鸟瞰图图像中检测汽车的方法。我正在使用 scikit 包来计算空 parking 场图像和有车的 parking 场的差异以检测异物。然后我画了汽车周围的最小面积矩形。

这在没有阴影的情况下效果很好。

空荡荡的 parking 场图片(请忽略栗色车)

Empty parking lot

没有阴影

Without shadows original

Without shadows threshold

Without shadows result

有阴影(问题)

当有车影时,也在最小面积矩形内。如何从矩形中排除阴影?

With shadows original

With shadows threshold

With shadows result

这是我的来源

import numpy as np
from skimage.measure import compare_ssim
import imutils
from cv2 import cv2

# construct the argument parse and parse the arguments
# load the two input images
imageA = cv2.imread('empty-lot.png')
imageB = cv2.imread('two-car-lot-shadow.png')

# convert the images to grayscale
grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)

# compute the Structural Similarity Index (SSIM) between the two
# images, ensuring that the difference image is returned
(score, diff) = compare_ssim(grayA, grayB, full=True, gaussian_weights=True, sigma=4)
diff = (diff * 255).astype("uint8")
print("SSIM: {}".format(score))

# threshold the difference image, followed by finding contours to
# obtain the regions of the two input images that differ
thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]

# loop over the contours
for c in cnts:
# compute the min area rect of the contour and area
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect)
area = cv2.contourArea(c)
# remove small contour areas
if area < 10000: continue
# convert all coordinates floating point values to int
box = np.int0(box)
# draw a green rectangle
cv2.drawContours(imageB, [box], 0, (0, 255, 0), 2)

# show the output images
cv2.imshow("Modified", imageB)
cv2.imshow("Thresh", thresh)
k = cv2.waitKey() & 0xFF
if k == 27:
exit()

最佳答案

可以将图片格式转成HSV格式,去除阴影很容易。

import ctypes
import numpy as np
import cv2
from pathlib import Path
from typing import List, Union, Callable


def main():
img_bgr: np.ndarray = cv2.imread(str(Path('parking.jpg')))
img_hsv: np.ndarray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(src=img_hsv, lowerb=np.array([0, 64, 153]), upperb=np.array([179, 255, 255]))
img_hsv_modify: np.ndarray = cv2.bitwise_and(img_bgr, img_bgr, mask=mask)
# show_img(img_hsv_modify)

img_mask_gray = cv2.cvtColor(img_hsv_modify, cv2.COLOR_BGR2GRAY)
threshold_val, img_bit = cv2.threshold(img_mask_gray, 0, 255, cv2.THRESH_BINARY) # type: float, np.ndarray
contours, hierarchy = cv2.findContours(img_bit, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

img_bgr_copy = np.copy(img_bgr)
for cnt in filter(lambda c: cv2.contourArea(c) > 10000, contours):
box = cv2.boxPoints(cv2.minAreaRect(cnt))
cv2.drawContours(img_bgr_copy, [np.int0(box)], -1, color=(0, 255, 0), thickness=2)

show_img([img_bgr, img_hsv_modify, cv2.cvtColor(img_bit, cv2.COLOR_GRAY2BGR), img_bgr_copy],
note=['original', 'hsv modify', 'bit', 'result'])
show_img(img_bgr_copy)


if __name__ == '__main__':
main()

你可能会问我怎么知道下限上限。 (请查看扩展代码:control_bar_hsv.py)

mask = cv2.inRange(src=img_hsv, lowerb=np.array([0, 64, 153]), upperb=np.array([179, 255, 255]))

结果:

enter image description here

所有图片:

enter image description here

扩展代码

显示图像:

def show_img(img_list: Union[np.ndarray, List[np.ndarray]], combine_fun: Callable = np.vstack,
window_name='demo', window_size=(ctypes.windll.user32.GetSystemMetrics(0) // 2, ctypes.windll.user32.GetSystemMetrics(1) // 2),
delay_time=0, note: Union[str, List[str]] = None, **options):
if isinstance(img_list, np.ndarray):
img_list = [img_list]

if isinstance(note, str):
print(note)

cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
if window_size:
w, h = window_size
cv2.resizeWindow(window_name, w, h)

result_list = []
for idx, img in enumerate(img_list):
img = np.copy(img)
if note and isinstance(note, list) and idx < len(note):
cv2.putText(img, note[idx], org=options.get('org', (50, 50)),
fontFace=options.get('fontFace', cv2.FONT_HERSHEY_SIMPLEX),
fontScale=options.get('fontScale', 2), color=(0, 255, 255), thickness=4)
result_list.append(img)
cv2.imshow(window_name, combine_fun(result_list))
cv2.waitKey(delay_time)

control_bar_hsv.py

它很容易使用,只需复制和粘贴,然后告诉它您的图像路径在哪里,就完成了。

如果您想创建其他 control_bar,也许 ControlBarBase 会帮助您编写更少的代码。

"""
control_bar_hsv.py
"""

import cv2
from pathlib import Path
import numpy as np
import ctypes
import functools
from typing import Tuple, Callable


class ControlBarBase:
__slots__ = ('img_bgr',)
WAIT_TIME = 500 # milliseconds
CONTROL_PANEL_NAME = 'control_panel'
IMAGE_PANEL_NAME = 'image'
SCREEN_SIZE: Tuple[int, int] = None

def __init__(self, img_path: Path):
self.img_bgr: np.ndarray = cv2.imread(str(img_path))
self.init_window()
self.init_track_bar()

def init_window(self):
for name in (self.CONTROL_PANEL_NAME, self.IMAGE_PANEL_NAME):
cv2.namedWindow(name, cv2.WINDOW_NORMAL)
if self.SCREEN_SIZE:
screen_width, screen_height = self.SCREEN_SIZE
cv2.resizeWindow(name, int(screen_width), int(screen_height))

def init_track_bar(self):
"""
self.build_track_bar(label_name, range_lim=(0, 255), default_value=0, callback)
"""
raise NotImplementedError('subclasses of _ControlBarBase must provide a init_track_bar() method')

def render(self):
raise NotImplementedError('subclasses of _ControlBarBase must provide a render() method.')

def build_track_bar(self, label_name: str,
range_lim: Tuple[int, int], default_value: int, callback: Callable = lambda x: ...):
min_val, max_val = range_lim
cv2.createTrackbar(label_name, self.CONTROL_PANEL_NAME, min_val, max_val, callback)
cv2.setTrackbarPos(label_name, self.CONTROL_PANEL_NAME, default_value)

def get_trackbar_pos(self, widget_name: str):
return cv2.getTrackbarPos(widget_name, self.CONTROL_PANEL_NAME)

def run(self):
while 1:
img, callback_func = self.render()
cv2.imshow(self.IMAGE_PANEL_NAME, img)
if (cv2.waitKey(self.WAIT_TIME) & 0xFF == ord('q') or
cv2.getWindowProperty(self.IMAGE_PANEL_NAME, 0) == -1 or
cv2.getWindowProperty(self.CONTROL_PANEL_NAME, 0) == -1):
callback_func()
break
cv2.destroyAllWindows()


class ControlBarHSV(ControlBarBase):
__slots__ = ()
WAIT_TIME = 500
SCREEN_SIZE = ctypes.windll.user32.GetSystemMetrics(0) / 2, ctypes.windll.user32.GetSystemMetrics(1) / 2

def init_track_bar(self):
self.build_track_bar('HMin', range_lim=(0, 179), default_value=0)
self.build_track_bar('SMin', (0, 255), 0)
self.build_track_bar('VMin', (0, 255), 0)

self.build_track_bar('HMax', (0, 179), 179)
self.build_track_bar('SMax', (0, 255), 255)
self.build_track_bar('VMax', (0, 255), 255)

def render(self):
# get current positions of all trackbars
h_min = self.get_trackbar_pos('HMin')
s_min = self.get_trackbar_pos('SMin')
v_min = self.get_trackbar_pos('VMin')

h_max = self.get_trackbar_pos('HMax')
s_max = self.get_trackbar_pos('SMax')
v_max = self.get_trackbar_pos('VMax')

# Set minimum and max HSV values to display
lower = np.array([h_min, s_min, v_min])
upper = np.array([h_max, s_max, v_max])

# Create HSV Image and threshold into a range.
hsv = cv2.cvtColor(self.img_bgr, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, lower, upper)
img_output: np.ndarray = cv2.bitwise_and(self.img_bgr, self.img_bgr, mask=mask)

@functools.wraps(self.render)
def cb_func():
return print(f'cv2.inRange(src=hsv, lowerb=np.array([{h_min}, {s_min}, {v_min}]), upperb=np.array([{h_max}, {s_max}, {v_max}]))')

return img_output, cb_func


if __name__ == '__main__':
from argparse import ArgumentParser

arg_parser = ArgumentParser()
arg_parser.add_argument("src_path", type=Path, help="source image path")
args = arg_parser.parse_args()
obj = ControlBarHSV(args.src_path) # ControlBarHSV(Path('parking.jpg'))
obj.run()

enter image description here

关于python-3.x - OpenCV-检测不包括阴影的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49333629/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com