Задать вопрос
Malodar
@Malodar
Начинающий питонист

Python Как обрезать изображения?

Привет всем! Помогите, пожалуйста, с одной проблемкой - у меня есть коллекция картинок (размером 550*500), типа таких:
dc6a0b9f3e144038813f2dbb64be2684.jpg3ef2b308c0f94d10914cedd312cf3ba5.jpgc7bc2f332ee04ed9882c5b9eecf4e562.jpg
Задача -- средствами Python обрезать серую рамку вокруг картинки, т.е. оставить только белую рамку и саму картинку. Вопрос - можно ли так сделать, учитывая, что границы этой белой рамки время от времени изменяются (как на второй картинке например)? Т.е. нельзя опытным путем подобрать границы изображения и просто кропнуть его через PIL.Image.crop()...
Буду благодарен за любой совет как мне поступить...
  • Вопрос задан
  • 4200 просмотров
Подписаться 4 Оценить Комментировать
Решения вопроса 2
@D3Nd3R
Дополню ответ Aleksey Solovyev.
1. Переводим в чб.
2. На бинарном изображении (вместо cv2.Canny необходимо применить cv2.threshold, так как цвет рамки - белый то подобрать порог будет нетрудно) необходимо найти внешний контур (cv2.findContours с параметром RETR_EXTERNAL) и затем останется сохранить часть изображения, которая лежит внутри контура.
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <algorithm>

int main(int argc, char *argv[])
{
	cv::Mat img,gr,th;
	img = cv::imread("1.jpg");
	cv::cvtColor(img, gr, cv::COLOR_BGR2GRAY);
	
	cv::threshold(gr, th, 240.0, 255, cv::THRESH_BINARY);

	std::vector<std::vector<cv::Point> > contours;
	cv::findContours(th, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);

	auto max_vector_comp = [](std::vector<cv::Point> &lhs,
		std::vector<cv::Point> &rhs)
	{
		return lhs.size() < rhs.size();
	};
	//поиск самого длинного контура
	auto maxVector = std::max_element(contours.begin(), contours.end(),
		max_vector_comp);
	//находим описывающий прямоугольник
	cv::Rect roi = cv::boundingRect(*maxVector);

	cv::Mat croppedImg;
	croppedImg = img(roi);
	cv::imshow("inImg", img);
	cv::imshow("croppedImg", croppedImg);
	cv::waitKey();
	return 0;
}
Ответ написан
alsolovyev
@alsolovyev
¯\_(ツ)_/¯ Enjoy life, Eat well & Laugh often
Не уверен в правильности решения(не сталкивался с такой проблемой. В PS это делается обычным макросом), но есть библиотека cv2

1- переводим в чб (что-то такое cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY) )
2 - выделяем область ( cv2.Canny(image, threshold1=123, threshold2=123))
3 - обрезаем
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Pythonpy
Ем за еду. Рисую за еду. Прогаю за еду.
Opencv в помощь.
Сканирующее окно работает с левого верхнего пикселя.
Изображение это двумерная матица размером x*y.
Ищем первую строку с пикселем белого цвета.
Отрезаем строки сверху.
Теперь делаем тоже самое, но только в обратную сторону, и запускаем сканирующее окно с конца.
Боковые серые стенки обрезаем по столбцам.
Не знаю на сколько эффективно, но это первое решение которое пришло в голову.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы