Я изучаю OpenCV, и я достиг точки, где, что бы я ни делал, я застреваю.
Я пытаюсь изолировать объект (прямоугольный объект) от фона.
Примером является следующее изображение батареи:
Я хочу замаскировать это изображение, чтобы единственное, что осталось, это объект.
Я пробовал следующее:
Но я получаю какую-то странную область как большую. Вот результирующие картинки:
Вот код, который я использую:
#include "opencv2/imgproc/imgproc.hpp"#include "opencv2/highgui/highgui.hpp"#include <stdlib.h>
#include <stdio.h>
using namespace cv;
using namespace std;int main( int, char** argv )
{
Mat src, srcGray,srcBlur,srcCanny;
string file = "samsung";
src = imread(file + ".jpg");
cvtColor(src, srcGray, CV_BGR2GRAY);
//bilateralFilter(srcGray, srcBlur,11, 17, 17);
srcBlur = srcGray.clone();
imshow("Filtered", srcBlur);
imwrite(file+"-filtered.jpg",srcBlur);
Canny(srcBlur, srcCanny, 0, 100, 3, true);
imshow("Canny", srcCanny);
imwrite(file+"-canny.jpg",srcCanny);vector< vector <Point> > contours; // Vector for storing contour
vector< Vec4i > hierarchy;
findContours( srcCanny.clone(), contours, hierarchy,CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the imageint largest_contour_index=0;
int largest_area=0;
for( int i = 0; i< contours.size(); i++ ){
double a=contourArea( contours[i],false); // Find the area of contour
if(a>largest_area){
largest_area=a;
largest_contour_index=i; //Store the index of largest contour
}
}Mat dst(src.rows,src.cols,CV_8UC1,Scalar::all(0)); //create destination image
drawContours( dst,contours, largest_contour_index, Scalar(255,0,0),CV_FILLED, 8, hierarchy );
imshow("Largest", dst);
imwrite(file+"-largest.jpg",dst);
waitKey();
}
Этот кусок кода был предназначен для получения «маски» объекта, затем необходимо применить маскирование, но я не могу двигаться вперед, потому что не могу обнаружить объект
Моя цель — обнаружить прямоугольные объекты (только один объект на изображение) на разных изображениях.
Идея была взята из Вот, но мне не удается заставить этот код работать с менее контрастным изображением, как у меня.
Я тоже попробую этот который почти так же, как я хочу.
Я хочу выделить прямоугольный объект (который должен быть больше на изображении)
Заранее спасибо!
PS: хотя я могу перевести Python на C ++, я был бы признателен за ответ непосредственно в C ++, чтобы я мог проверить его быстрее.
Это то, что я взломал вместе, извините, это в Python 🙂
Во-первых, измените размер изображения до 1/4 от исходного размера (вероятно, он будет работать без изменения размера, хотя и с другими параметрами) и примените медианное размытие:
w, h, c = img_in.shape #img_in is the input image
resize_coeff = 0.25
img = cv2.resize(img_in, (int(resize_coeff*h), int(resize_coeff*w)))
img = cv2.medianBlur(img, 15)
Что хорошего в срединном размытии, так это в том, что он удаляет большую часть шума и мелких ненужных деталей, таких как эти синие линии маркера, сохраняя края более крупных фигур не размытыми. Теперь давайте применим обнаружение краев Canny:
img = cv2.Canny(img, 100, 200)
К сожалению, на наших краях есть несколько крошечных зазоров, но это можно исправить с помощью расширения / разрушения:
kernel = np.ones((17, 17), np.uint8)
img = cv2.dilate(img, kernel, 1)
img = cv2.erode(img, kernel, 1)
Теперь мы можем найти наши контуры, взять самый большой по площади, и это, вероятно, будет тем, что мы хотим:
img, contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
max_index, max_area = max(enumerate([cv2.contourArea(x) for x in contours]), key = lambda x: x[1])
max_contour = contours[max_index]
Рисуя его поверх исходного (масштабированного) изображения, мы получим это:
img_out = cv2.resize(img_in, (int(resize_coeff*h), int(resize_coeff*w)))
cv2.drawContours(img_out, [max_contour], 0, (0, 0, 255), 2)
С помощью простого сглаживания контуров мы можем легко избавиться от проводов сверху, если захотим. Не знаю, что делать с тенью внизу.
Ваше входное изображение слишком велико, чтобы найти грубую последовательность контуров. Для изображений с более высоким разрешением вывод будет более детальным. В случае высокого разрешения, это не один контур, соответствующий наибольшему прямоугольнику. Так что решение
1. либо измените размер изображения, чтобы уменьшить, как я изменил размер изображения
resize(srcGray, srcGray, Size(), 0.25, 0.25);
и я получил этот вывод
(opencv) объединить контуры вместе
Но я бы предложил лучшее решение — изменить размер, а затем применить тот же код. Это легко и менее сложно.
ЗАМЕЧАНИЕ: выход здесь соответствует внутреннему прямоугольнику, вы можете дополнительно отрегулировать коэффициент изменения размера и пороговый коэффициент хитрости