2014-07-06 4 views
0

Я изображение с размером (352 х 240)
enter image description hereНайти площадь прямоугольника изображения, чтобы обрезать

И я хочу, чтобы обрезать белую область (выделенную область, как показано ниже).
enter image description here

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

private static Image cropImage(Image img, Rectangle cropArea) 
{ 
    Bitmap bmpImage = new Bitmap(img); 
    Bitmap bmpCrop = bmpImage.Clone(cropArea, 
    bmpImage.PixelFormat); 
    return (Image)(bmpCrop); 
} 

Но я не могу найти точную прямоугольную область для моей потребности!
Как найти Rectangle значение выбранной области?
Я просто хочу обрезать эту область !! Благодаря !

+1

Я думаю, вам нужно работать с пакетом Aforge.NET - он обеспечивает функциональность для этой проблемы - и многие другие - – yossico

+0

Спасибо @Yossico, но я не хочу, чтобы какой-либо сторонний инструмент. Я просто хочу знать значение «Прямоугольник» выбранной области моего второго изображения :). – zey

ответ

2

Если вы хотите сделать это самостоятельно, вы, безусловно, сможете. Но детали того, как это сделать лучше всего, будут зависеть от того, насколько вы знаете об исходном изображении.

Вот несколько вопросов и решения, рассмотреть следующие вопросы:

  • вы знаете что-то о размерности образа
  • вы знаете, что-то о положении изображения, будет всегда находиться в внизу справа?
  • Знаете ли вы что-то о размерах разрезанных углов?
  • Знаете ли вы цвета?
  • Вы бы предпочли сократить потери некоторых пикселей внутри или включить некоторые пиксели снаружи или в середине?

Глядя на вашем примере вы могли бы, например, попробовать эту стратегию:

  • Сначала вы траверс изображения по горизонтали на некоторых расстояниях, скажем, на срезах 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 в неправильном месте. Исправленный.

+0

Да, размер изображения всегда (352 x 240), и область, которую я хочу обрезать, также находится в этом положении! – zey

+0

@zey: см. Мою коррекцию! – TaW

Смежные вопросы