Есть ли способ загрузки изображений лучше с OpenCV - PullRequest
1 голос
/ 04 ноября 2019

Я хочу загрузить изображения и использовать грубое преобразование, чтобы захватить черную ограниченную область внутри бумаги, а затем выполнить несколько операций подсчета внутри коробок. Естественно, для этого требуется, чтобы я мог загружать изображения в относительно хорошем качестве.

Проблема заключается в том, что при загрузке с использованием cv2.imread () openCV я получаю очень размытую версию изображения, которую я могу 'т процесс быстро. Что еще хуже, я не могу отобразить изображение с помощью cv2.imshow (), моя среда IDE зависает каждый раз, когда я пытаюсь его увидеть. Поэтому я должен использовать matplotlib для рендеринга и просмотра изображения шаг за шагом.

Я не знаю других пакетов для обработки изображений (возможно, подушки, но я не знаю, будет ли это делать то, что мне нужно)это сделать).

Мое исходное изображение выглядит так: original image

img = cv2.imread("img1-min.jpg")

Поскольку метод cv2.imshow () приводит к сбою окна,Я прибег к matplotlib:

plt.imshow(img)
plt.title('my picture')
plt.show()

Результат: enter image description here

После этого:

gray = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 75, 150)
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 50, 50, 5)

if lines is not None:
    for line in lines:
        x1, y1, x2, y2 = line[0]
        cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 5)

plt.imshow(img)
plt.title('my picture')
plt.show()

Вывод:

enter image description here

Как видите, очень грязно. Я догадываюсь, что это из-за способа загрузки исходного изображения. Есть ли способ улучшить процесс загрузки, чтобы было проще наносить линии Hough?

1 Ответ

4 голосов
/ 05 ноября 2019

Я считаю, что изображение нормально загружается с cv2.imread(), но оно настолько велико с размером 2976x3838, что у вашей IDE возникли проблемы с отображением изображения. Я полагаю, что вы применяете cv2.HoughLinesP() неправильно. Вместо использования cv2.HoughLinesP(), есть альтернативный подход для обнаружения линий


Идея состоит в том, чтобы пороговым значением затем найти ограничивающий прямоугольник доски для создания маски. Из этой маски мы выполняем перспективное преобразование для получения изображения сверху вниз. Это позволит нам лучше обнаруживать линии

image image

Как только у нас будет обнаруженная плата, мы можем извлечь ROI

image

Затем мы просто обнаруживаем вертикальные и горизонтальные линии

image image

Результат

image

import cv2
import numpy as np

def perspective_transform(image, corners):
    def order_corner_points(corners):
        # Separate corners into individual points
        # Index 0 - top-right
        #       1 - top-left
        #       2 - bottom-left
        #       3 - bottom-right
        corners = [(corner[0][0], corner[0][1]) for corner in corners]
        top_r, top_l, bottom_l, bottom_r = corners[0], corners[1], corners[2], corners[3]
        return (top_l, top_r, bottom_r, bottom_l)

    # Order points in clockwise order
    ordered_corners = order_corner_points(corners)
    top_l, top_r, bottom_r, bottom_l = ordered_corners

    # Determine width of new image which is the max distance between 
    # (bottom right and bottom left) or (top right and top left) x-coordinates
    width_A = np.sqrt(((bottom_r[0] - bottom_l[0]) ** 2) + ((bottom_r[1] - bottom_l[1]) ** 2))
    width_B = np.sqrt(((top_r[0] - top_l[0]) ** 2) + ((top_r[1] - top_l[1]) ** 2))
    width = max(int(width_A), int(width_B))

    # Determine height of new image which is the max distance between 
    # (top right and bottom right) or (top left and bottom left) y-coordinates
    height_A = np.sqrt(((top_r[0] - bottom_r[0]) ** 2) + ((top_r[1] - bottom_r[1]) ** 2))
    height_B = np.sqrt(((top_l[0] - bottom_l[0]) ** 2) + ((top_l[1] - bottom_l[1]) ** 2))
    height = max(int(height_A), int(height_B))

    # Construct new points to obtain top-down view of image in 
    # top_r, top_l, bottom_l, bottom_r order
    dimensions = np.array([[0, 0], [width - 1, 0], [width - 1, height - 1], 
                    [0, height - 1]], dtype = "float32")

    # Convert to Numpy format
    ordered_corners = np.array(ordered_corners, dtype="float32")

    # Find perspective transform matrix
    matrix = cv2.getPerspectiveTransform(ordered_corners, dimensions)

    # Return the transformed image
    return cv2.warpPerspective(image, matrix, (width, height))

image = cv2.imread('1.jpg')
original = image.copy()
blur = cv2.bilateralFilter(image,9,75,75)
gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray,0,255, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV)[1]

cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

mask = np.zeros(image.shape, dtype=np.uint8)
for c in cnts:
    area = cv2.contourArea(c)
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.015 * peri, True)

    if area > 150000 and len(approx) == 4:
        cv2.drawContours(image,[c], 0, (36,255,12), 3)
        cv2.drawContours(mask,[c], 0, (255,255,255), -1)
        transformed = perspective_transform(original, approx)

mask = cv2.bitwise_and(mask, original)

# Remove horizontal lines
gray = cv2.cvtColor(transformed, cv2.COLOR_BGR2GRAY)
board_thresh = cv2.threshold(gray,0,255, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV)[1]
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (55,1))
detect_horizontal = cv2.morphologyEx(board_thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detect_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(transformed, [c], -1, (36,255,12), 9)
    pass

# Remove vertical lines
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,55))
detect_vertical = cv2.morphologyEx(board_thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=2)
cnts = cv2.findContours(detect_vertical, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(transformed, [c], -1, (36,255,12), 9)

cv2.imwrite('thresh.png', thresh)
cv2.imwrite('image.png', image)
cv2.imwrite('mask.png', mask)
cv2.imwrite('transformed.png', transformed)
cv2.waitKey()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...