Если вы хотите сделать это самостоятельно, вы, безусловно, сможете. Но детали того, как это сделать лучше всего, будут зависеть от того, насколько вы знаете об исходном изображении.
Вот несколько вопросов и решения, рассмотреть следующие вопросы:
- вы знаете что-то о размерности образа
- вы знаете, что-то о положении изображения, будет всегда находиться в внизу справа?
- Знаете ли вы что-то о размерах разрезанных углов?
- Знаете ли вы цвета?
- Вы бы предпочли сократить потери некоторых пикселей внутри или включить некоторые пиксели снаружи или в середине?
Глядя на вашем примере вы могли бы, например, попробовать эту стратегию:
- Сначала вы траверс изображения по горизонтали на некоторых расстояниях, скажем, на срезах 10 или 20.
- На каждом трансверсаль вы наблюдаете и собираете все точки, где пиксель меняет цвет
- , то вы сравниваете результирующие списки, чтобы увидеть, есть ли в середине (!), которые согласны
- это дает вам левый и правый границы
- он также дает вам область, где вы сможете выполнять вертикальные сканирования
- затем вы повторяете для вертикального сканирования, чтобы получить верхнюю и нижнюю координаты.
- вертикальные развертки не должны искать прямоугольник, они могут работать с середины результатов горизонтального сканирования
Для этой работы вы должны знать немного об изменениях цветов вы ожидаете : Будет ли сглаживание вовлечено? Если да, то какой уровень изменения вам нужен, чтобы сравнить результат GetPixel
цветов ..?
Также размеры должны быть либо известны приблизительно, иначе вам могут понадобиться повторить весь процесс с более тонкой сеткой ..
Edit: Используя информацию из вашего комментария можно сделать несколько предположений (*) и используйте этот фрагмент кода для определения целевого прямоугольника.Допущения используются для:
- определить два диапазона строки принадлежит где сканированию можно предположить, чтобы ударить тело мишени
- определяет два пикселя с внутренним и внешним цветом
я использую функцию координированности и 4 списка очков и среднее число нескольких хитов. Переменная blur
работает со значениями 2-6 для вашего изображения.
List<Point> xPoints1 = new List<Point>();
List<Point> xPoints2 = new List<Point>();
List<Point> yPoints1 = new List<Point>();
List<Point> yPoints2 = new List<Point>();
Rectangle findRectangle()
{
int xMax = pictureBox1.Image.Width;
int yMax = pictureBox1.Image.Height;
// * we can asume that these lines hit the body
int x0 = xMax * 3/4;
int y0 = yMax * 3/4;
using (Bitmap bmp = new Bitmap(pictureBox1.Image))
{
// we can assume that these are the out- and inside colors
Color col0 = bmp.GetPixel(9, 9);
Color col1 = bmp.GetPixel(x0, y0);
int blur = 4;
int diff = colordistance(col0, col1)/blur;
bool outside = true;
// a few horizontal scans..
for (int y = y0 - 20; y < y0 + 20; y += 4)
{
outside = true;
for (int x = 0; x < xMax; x++)
{
Color c = bmp.GetPixel(x, y);
if (outside && colordistance(c, col0) > diff)
{ outside = !outside; xPoints1.Add(new Point(x, y)); }
else if (!outside && colordistance(c, col1) > diff)
{ outside = !outside; xPoints2.Add(new Point(x, y)); }
}
}
// a few vertical scans..
for (int x = x0 - 20; x < x0 + 20; x += 4)
{
outside = true;
for (int y = 0; y < yMax; y++)
{
Color c = bmp.GetPixel(x, y);
if (outside && colordistance(c, col0) > diff)
{ outside = !outside; yPoints1.Add(new Point(x, y)); }
else if (!outside && colordistance(c, col1) > diff)
{ outside = !outside; yPoints2.Add(new Point(x, y)); }
}
}
int left = (int)xPoints1.Average(p => p.X);
int right = (int)xPoints2.Average(p => p.X);
int top = (int)yPoints1.Average(p => p.Y);
int bottom = (int)yPoints2.Average(p => p.Y);
// if the target sits at the bottom we didn't find the edge
if (bottom == 0) bottom = yMax;
return = new Rectangle(left, top, right - left, bottom - top);
}
}
int colordistance(Color c1, Color c2)
{
return (int) Math.Sqrt((c1.R - c2.R) * (c1.R - c2.R) +
(c1.G - c2.G) * (c1.G - c2.G) +
(c1.B - c2.B) * (c1.B - c2.B));
}
Примечание: верхние и левое значение попало внутрь мишени. Дно (и, возможно, дно) попало наружу. Таким образом, вы должны уменьшить либо первый, либо последний на 1 пиксель, в зависимости от ваших потребностей ..!
Редактировать В первой версии была установлена переменная outside
в неправильном месте. Исправленный.
Я думаю, вам нужно работать с пакетом Aforge.NET - он обеспечивает функциональность для этой проблемы - и многие другие - – yossico
Спасибо @Yossico, но я не хочу, чтобы какой-либо сторонний инструмент. Я просто хочу знать значение «Прямоугольник» выбранной области моего второго изображения :). – zey