0

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

enter image description hereenter image description here enter image description here

enter image description hereenter image description here enter image description here

+0

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

+0

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

+0

А также покажите фрагмент кода того, что у вас есть. Связано это с Opencv? Если да, добавьте тег. – kebs

ответ

5

Решение Объяснение

я предлагаю следующий подход:

  1. генерировать первоначальное предположение для 4 углов формы в соответствии с геометрическими свойствами (подробнее см. Код ниже).

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

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

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

код

%reads image 
gray = rgb2gray(imread('Bqx51.png')); 
I = gray>0; 

%extract boundries 
B = bwboundaries(I,8); 
B = B{1}; 
boundriesImage = zeros(size(I)); 
boundriesImage(sub2ind(size(I),B(:,1),B(:,2))) = 1; 

%finds best 4 corners 
[ corners ] = optimizeCorners(B); 

%generate line mask 
linesMask = drawLines(size(I),corners,corners([2:4,1],:)); 

%fill holes 
rectMask = imfill(linesMask,'holes'); 

%noise reduction 
rectMask = I & rectMask; 
rectMask = imopen(rectMask,strel('disk',2)); 

%calculate result 
result = gray; 
result(~rectMask) = 0; 

%display results 
figure,imshow([gray, 255*ones(size(I,1),1),result]); 

функция угловой оптимизации

function [ corners] = optimizeCorners(pnts) 
%OPTIMIZE4PTS Summary of this function goes here 
% Detailed explanation goes here 

Y = pnts(:,1); 
X = pnts(:,2); 

corners = getInitialGuess(X,Y); 
boundriesIm = zeros(max(Y),max(X)); 
boundriesIm(sub2ind(size(boundriesIm),pnts(:,1),pnts(:,2))) = 1; 

%R represents the search radius 
R = 3; 

%continue optimizing as long as there is no change in the final result 
unchangedIterations = 0; 
while unchangedIterations<4 

    for ii=1:4 
     %optimize corner ii 
     currentCorner = corners(ii,:); 
     bestCorner = currentCorner; 
     bestRes = calcEnergy(boundriesIm,corners); 
     cornersToEvaluate = corners; 
     candidateInds = sum(((repmat(currentCorner,size(X,1),1)-[Y,X]).^2),2)<(R^2); 
     candidateCorners = [Y(candidateInds),X(candidateInds)]; 
     for jj=length(candidateCorners) 
      xx = candidateCorners(jj,2); 
      yy = candidateCorners(jj,1); 
      cornersToEvaluate(ii,:) = [yy,xx]; 
      res = calcEnergy(boundriesIm,cornersToEvaluate); 
      if res > bestRes 
       bestRes = res; 
       bestCorner = [yy,xx]; 
      end 
     end 
     if isequal(bestCorner,currentCorner) 
      unchangedIterations = unchangedIterations + 1; 
     else 
      unchangedIterations = 0; 
      corners(ii,:) = bestCorner; 

     end 
    end 
end 

end 

функция Вычислить энергию

function res = calcEnergy(boundriesIm,corners) 
%calculates the score of the corners list, given the boundries image. 
%the result is acutally the jaccard index of the boundries map and the 
%lines map 
linesMask = drawLines(size(boundriesIm),corners,corners([2:4,1],:)); 
res = sum(sum(linesMask&boundriesIm))/sum(sum(linesMask|boundriesIm)); 

end 

найти начальное предположение для углов функционирования

function corners = getInitialGuess(X,Y) 
%calculates an initial guess for the 4 corners 

corners = zeros(4,2); 

%preprocessing stage 
minYCoords = find(Y==min(Y)); 
maxYCoords = find(Y==max(Y)); 
minXCoords = find(X==min(X)); 
maxXCoords = find(X==max(X)); 
%top corners 
topRightInd = find(X(minYCoords)==max(X(minYCoords)),1,'last'); 
topLeftInd = find(Y(minXCoords)==min(Y(minXCoords)),1,'last'); 
corners(1,:) = [Y(minYCoords(topRightInd)) X((minYCoords(topRightInd)))]; 
corners(2,:) = [Y(minXCoords(topLeftInd)) X((minXCoords(topLeftInd)))]; 
%bottom corners 
bottomRightInd = find(Y(maxXCoords)==max(Y(maxXCoords)),1,'last'); 
bottomLeftInd = find(X(minYCoords)==min(X(minYCoords)),1,'last'); 
corners(4,:) = [Y(maxXCoords(bottomRightInd)) X((maxXCoords(bottomRightInd)))]; 
corners(3,:) = [Y(maxYCoords(bottomLeftInd)) X((maxYCoords(bottomLeftInd)))]; 


end 

функция DrawLine (взятый из следующего answer, по @Suever)

function mask = drawLines(imgSize, P1, P2) 
%generates a mask with lines, determine by P1 and P2 points 

mask = zeros(imgSize); 

P1 = double(P1); 
P2 = double(P2); 

for ii=1:size(P1,1) 
    x1 = P1(ii,2); y1 = P1(ii,1); 
    x2 = P2(ii,2); y2 = P2(ii,1); 

    % Distance (in pixels) between the two endpoints 
    nPoints = ceil(sqrt((x2 - x1).^2 + (y2 - y1).^2)); 

    % Determine x and y locations along the line 
    xvalues = round(linspace(x1, x2, nPoints)); 
    yvalues = round(linspace(y1, y2, nPoints)); 

    % Replace the relevant values within the mask 
    mask(sub2ind(size(mask), yvalues, xvalues)) = 1; 
end 

Результаты

первое изображение (до и после):

enter image description here

второй изображение (до и после):

enter image description here

среды выполнения

Elapsed time is 0.033998 seconds. 

Возможные улучшения/предложения

  1. Функция энергии может также включать в себя ограничения, которые стимулируют параллельные линии имеют аналогичные склоны (в ваш пример не имеет одинакового наклона).

  2. Функция энергии может включать ограничения, которые поощряют угол наклона каждого угла до 90 градусов.

  3. можно выполнить ступени уменьшения шума (например, imclose), прежде чем выполнять этот подход для устранения небольших артефактов.

  4. Возможно запустить алгоритм с несколькими исходными догадками и выбрать лучший.

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