首页 > 解决方案 > 用于图像处理和保存的循环函数导致错误 - 预期 Ptr对于参数“%s”

问题描述

我正在研究图像上的车道检测。我有一个函数,它获取图像的路径并返回检测到车道的图像。我需要编写另一个函数,它将一个包含多个图像和输出路径的目录的路径作为输入,使用第一个函数处理图像,然后将其保存在输出目录中。

这是一开始的代码,如果你想重现它,我会在其中定义辅助函数:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import cv2
%matplotlib inline

def to_gray(image):
    gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
    return gray

def blur_gray(gray):
    kernel_size = 5
    blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size),0)
    return blur_gray

def Canny(blur_gray):
    low_threshold = 100
    high_threshold = 200
    edges = cv2.Canny(blur_gray, low_threshold, high_threshold)
    return edges

def masked_edges(image, edges):
    mask = np.zeros_like(edges)   
    ignore_mask_color = 255  
    imshape = image.shape
    vertices = np.array([[(130,imshape[0]),(420, 325), (540,325), (850,imshape[0])]], dtype=np.int32)
    cv2.fillPoly(mask, vertices, ignore_mask_color)
    masked_edges = cv2.bitwise_and(edges, mask)
    return masked_edges

def lines (masked_edges, image):
    # Define the Hough transform parameters
    # Make a blank the same size as our image to draw on
    rho = 1 # distance resolution in pixels of the Hough grid
    theta = np.pi/180 # angular resolution in radians of the Hough grid
    threshold = 1     # minimum number of votes (intersections in Hough grid cell)
    min_line_length = 3 #minimum number of pixels making up a line
    max_line_gap = 4    # maximum gap in pixels between connectable line segments
    line_image = np.copy(image)*0 # creating a blank to draw lines on

    # Run Hough on edge detected image
    # Output "lines" is an array containing endpoints of detected line segments
    lines = cv2.HoughLinesP(masked_edges, rho, theta, threshold, np.array([]),
                                min_line_length, max_line_gap)
    return lines

def draw_lines(lines, image, edges):
    line_image = np.copy(image)*0 # creating a blank to draw lines o
    # Iterate over the output "lines" and draw lines on a blank image
    for line in lines:
        for x1,y1,x2,y2 in line:
            cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),10)

    # Create a "color" binary image to combine with line image
    color_edges = np.dstack((edges, edges, edges)) 

    # Draw the lines on the edge image
    lines_edges = cv2.addWeighted(color_edges, 0.8, line_image, 1, 0) 
    pic_lanes = plt.imshow(lines_edges)
    return pic_lanes

所以这个函数结合了上面的多个辅助函数并返回一个图像:

def image_pipeline(image_path):
  image = mpimg.imread(image_path)
  gray = to_gray(image)
  to_blur_gray = blur_gray(gray)
  edges = Canny(to_blur_gray)
  masked = masked_edges(image, edges)
  line = lines(masked, image)
  pic_lanes = draw_lines(line, image, edges)
  return pic_lanes

上面函数返回的图片

然后我想在一个循环函数中使用上述函数,该函数将对输入目录中的所有图像执行相同的操作并将它们保存在输出目录中。

def video_loop(outPath, path):
  image_no = 1
  for image_path in os.listdir(path):
        
        # create the full input path and read the file
        input_path = os.path.join(path, image_path)
        pic_lanes = image_pipeline(input_path)
        fullpath = os.path.join(outPath, image_path)
        name = fullpath + '.jpg'
        cv2.imwrite(name, pic_lanes)
        os.chdir(fullpath)
        image_no += 1
if __name__ == '__video_loop__':
    video_loop()
out= '/content/CarND-LaneLines-P1/Solid White Frames Canny'
path1 = '/content/CarND-LaneLines-P1/Frames Solid White Right'
video_loop(out, path1)

不幸的是,我收到一个错误以及一张返回的图像:

TypeError                                 Traceback (most recent call last)
<ipython-input-109-10dea7ed1446> in <module>()
      1 out= '/content/CarND-LaneLines-P1/Solid White Frames Canny'
      2 path1 = '/content/CarND-LaneLines-P1/Frames Solid White Right'
----> 3 video_loop(out, path1)

<ipython-input-108-a52f4438bc0d> in video_loop(outPath, path)
      8         fullpath = os.path.join(outPath, image_path)
      9         name = fullpath + '.jpg'
---> 10         cv2.imwrite(name, pic_lanes)
     11         os.chdir(fullpath)
     12         image_no += 1

TypeError: Expected Ptr<cv::UMat> for argument '%s'

我已经搜索了这个错误的含义,有人建议cv2.imwrite()没有得到有效的参数(图片不存在),但我不知道如何解决这个问题。

编辑:我也尝试过像这样更简单的东西:

count=0
for filename in os.listdir('/content/CarND-LaneLines-P1/Frames Solid White Right'):
  detected_lanes = image_pipeline(filename)
  detected_lanes = cv2.imread(detected_lanes)
  cv2.imwrite(filename, detected_lanes)
  os.chdir('/content/CarND-LaneLines-P1/Frames Solid White Right/Canny')
  count =+1

但我在这里遇到了一个不同的错误:

SystemError                               Traceback (most recent call last)
<ipython-input-15-1d3fff5ab2bb> in <module>()
      2 for filename in os.listdir('/content/CarND-LaneLines-P1/Frames Solid White Right'):
      3   detected_lanes = image_pipeline(filename)
----> 4   detected_lanes = cv2.imread(detected_lanes)
      5   cv2.imwrite(filename, detected_lanes)
      6   os.chdir('/content/CarND-LaneLines-P1/Frames Solid White Right/Canny')

SystemError: <built-in function imread> returned NULL without setting an error

我不知道如何处理这个问题。如果您想运行此代码,只需使用提供的代码,然后使用image_pipeline并传递任何图像。

你有机会在这里帮我吗?

标签: pythonopencvmachine-learningcomputer-vision

解决方案


我设法通过在我的管道中传递一个保存函数来解决我的问题,然后才运行一个循环。首先,我更改了draw_lines功能以保存图像:

def draw_lines(lines, image, edges, image_path, path_to_save_files):
    copy = np.copy(image)
    line_image = np.copy(image)*0 # creating a blank to draw lines o
    # Iterate over the output "lines" and draw lines on a blank image
    for line in lines:
        for x1,y1,x2,y2 in line:
            cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),10)

    # Create a "color" binary image to combine with line image
    color_edges = np.dstack((edges, edges, edges)) 
    # Draw the lines on the edge image
    my_dpi=96
    lines_edges = cv2.addWeighted(color_edges, 0.8, line_image, 1, 0) 
    final = cv2.addWeighted(lines_edges, 0.5, image, 0.7, 50)
  
    plt.figure(figsize=(960/my_dpi, 540/my_dpi), dpi=my_dpi)
    final_image = plt.imshow(final)
    plt.axis('off')
    save_fname = os.path.join(outpath, os.path.basename(image_path))
    plt.savefig(save_fname, bbox_inches='tight', pad_inches=0, transparent=True)  

plt.savefig()通过传递它save_fname来使用它,它会随着每个图像而相应更改(它需要我想要存储图像的目录的路径以及从其原始路径派生的文件的名称)。此外,我不希望我的图片采用矩阵形式,所以我使用了plt.axis('off').

然后我使用了一个简单的 for 循环:

count= 0
  for file in os.listdir(path_with_images):
    image_pipeline(file, path_to_save_files)
    count=+1

这对我很有用。


推荐阅读