Использование OpenCV для обрезки изображения с фона (извлечение полосы) - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь извлечь секцию пэда из следующего изображения с помощью OpenCv. Начиная с изображения, подобного этому: strip with background

Я пытаюсь извлечь в изображение, подобное этому:

enter image description here

чтобы в итоге получилось что-то вроде этого

enter image description here

В настоящее время у меня есть следующие

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('strip.png')

grayscale = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresholded = cv2.threshold(grayscale, 0, 255, cv2.THRESH_OTSU)
bbox = cv2.boundingRect(thresholded)
x, y, w, h = bbox
foreground = img[y:y+h, x:x+w]

cv2.imwrite("output.png", foreground)

Какие выходы это:

enter image description here

1 Ответ

1 голос
/ 30 марта 2020

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

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

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

Затем я сделал морфологию, чтобы удалить зашумленные остатки процесса. В конце с помощью команды boundingRect я извлек нужный сегмент (белый контур):

удален фон:

enter image description here

разностное изображение после размытия с эрозией:

enter image description here

разностное изображение после процесса открытия и порог:

enter image description here

И, наконец, ограничивающий прямоугольник белых объектов:

enter image description here

Код, который я написал (C ++ opencv) :

Mat im = imread("E:/t.jpg", 0);
resize(im, im, Size() , 0.3, 0.3); // # resizing just for better visualization

Mat im1,im2, im3;

// Removing the black background:
threshold(im, im1, 50, 255, THRESH_BINARY);
vector<vector<Point>> contours_1;
findContours(im1, contours_1, RETR_CCOMP, CHAIN_APPROX_NONE);

Rect r = boundingRect(contours_1[0]);

im(r).copyTo(im);
im.copyTo(im3);

imshow("background removed", im); 

// detecting the cluttered parts and cut them:
erode(im, im2, Mat::ones(3, 3, CV_8U), Point(-1, -1), 3);

im2.convertTo(im2, CV_32F);
im3.convertTo(im3, CV_32F);
subtract(im2, im3, im1);

double min, max;
minMaxIdx(im1, &min, &max);
im1 = 255*(im1 - min) / (max - min);
im1.convertTo(im1, CV_8U);

imshow("the difference image", im1);

threshold(im1, im1, 250, 255, THRESH_BINARY);

erode(im1, im1, Mat::ones(3, 3, CV_8U), Point(-1, -1), 3);
dilate(im1, im1, Mat::ones(3, 3, CV_8U), Point(-1, -1), 7);

imshow("the difference image thresholded", im1);

vector<Point> idx, hull;
vector<vector<Point>> hullis;
findNonZero(im1, idx);
Rect rr = boundingRect(idx);

rectangle(im, rr, Scalar(255, 255, 255), 2);

imshow("Final segmentation", im);

waitKey(0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...