#python #image #opencv #image-processing
#python #изображение #opencv #обработка изображений
Вопрос:
Некоторые собственные (или 3-е) модули, которые обеспечивали функцию, превосходны, но для меня этого недостаточно.
простой пример
например, builtins.print
если мне нужно напечатать ...
в конце для всех вариантов печати, что я могу сделать?
Я знаю, что приведенный выше вопрос слишком глуп, но я хочу, чтобы все, кто может быстро присоединиться, поэтому я выбираю его в качестве примера.
пример2
И если вы спросите меня, чего вы на самом деле хотите?
imutils.perspective.four_point_transform
Вы можете увидеть код ниже: ( imutils
: version = 0.5.3)
# imutils.perspective.py
def four_point_transform(image, pts):
...
M = cv2.getPerspectiveTransform(rect, dst)
warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight)) # <-- so close, If that provide any options (kwargs) will perfect!
# ↑ I want all the code of **four_point_transform** to keep original except this line. for example,
# warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight), borderMode=cv2.BORDER_CONSTANT, borderValue=(255, 255, 255))
return warped
Итак, если мне нужно залить цвет белым цветом, то мне нужно написать больше кода для достижения этого.
И этот способ не то, что я хочу.
оригинал
Результат
ожидаемый результат
более подробная информация о example2
Если вам нужен полный код example2, скопируйте и вставьте его.
import imutils.perspective
import cv2
import numpy as np
import sys
from pathlib import Path
def show_img(img: np.ndarray, window_name='demo', window_size=(200, 200), delay_time=0, note: str = None):
if note:
print(note)
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
w, h = window_size
cv2.resizeWindow(window_name, w, h)
cv2.imshow(window_name, img)
cv2.waitKey(0)
def get_single_contour(img: np.ndarray, fit_range=None):
if fit_range is None:
fit_range = [_ for _ in range(20)]
for kernel_size in fit_range:
size = (kernel_size, kernel_size)
kernel: np.ndarray = cv2.getStructuringElement(cv2.MORPH_RECT, size)
img_dilate: np.ndarray = cv2.dilate(img, kernel, iterations=2)
contour_list, hierarchy = cv2.findContours(img_dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
show_img(img_dilate)
assert isinstance(contour_list[0], np.ndarray), TypeError
if len(contour_list) != 1:
continue
print(f'use kernel_size={kernel_size}')
return contour_list[0]
sys.stderr.write(f'It no kernel-size({fit_range!r}) that can make the size of contour equal to one.')
return -1
def do_perspective(target_img: np.ndarray, contour: np.ndarray, show=True) -> np.ndarray:
rect = ((center_x, center_y), (width, height), rotate_theta) = cv2.minAreaRect(contour)
box: np.ndarray = cv2.boxPoints(rect)
if show:
img_temp = np.copy(target_img)
cv2.drawContours(img_temp, [contour], -1, (0, 255, 0), 2)
show_img(img_temp, note='single_contour')
img_perspective: np.ndarray = imutils.perspective.four_point_transform(target_img, box)
return img_perspective
def main():
img_bgr: np.ndarray = cv2.imread(str(Path('JAN.png')))
img_gray: np.ndarray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)
threshold_value, img_bit = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
contour = get_single_contour(img_bit, np.arange(3, 15, 2))
img_perspective = do_perspective(img_bgr, contour)
show_img(img_perspective)
if __name__ == '__main__':
main()
заключение
Существует ли способ решить это во всех случаях?
Ответ №1:
Вот мое решение,
from contextlib import contextmanager
import functools
@contextmanager
def add_extra_para(module, prop: str, *extra_para, **extra_options):
org_func = getattr(module, prop)
if not callable(org_func):
raise RuntimeError(f'{org_func!r} is not callable')
def wrap_new_func(*para, **options):
@functools.wraps(org_func)
def original_func(*args, **kwargs):
kwargs.update(options)
args = [*args] [*para]
return org_func(*args, **kwargs)
return original_func
try:
target_function = wrap_new_func(*extra_para, **extra_options)
setattr(module, prop, target_function)
yield
finally:
setattr(module, prop, org_func)
используйте его в примере 1
import builtins
with add_extra_para(builtins, 'print', '...'):
print('Apple', 'Banana') # output: Apple Banana ...
# The function is back to the original after it leaving the With.
print('Apple', 'Banana') # output: Apple Banana
используйте его в example2
def do_perspective(target_img: np.ndarray, contour: np.ndarray, show=True) -> np.ndarray:
...
with add_extra_para(cv2, 'warpPerspective', borderMode=cv2.BORDER_CONSTANT, borderValue=(255, 255, 255)):
img_perspective: np.ndarray = imutils.perspective.four_point_transform(target_img, box)
return img_perspective