Аватар для dexter007
4 / 4 / 0
Регистрация: 10.10.2012
Сообщений: 27

Разбить изображения на 20 ровных сектора и подсчитать количество черных пикселов в каждом из найденых секторов

18.03.2015, 09:41. Показов 8761. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Задача заключается в следующем. Нужно разбить изображение на 20 равных частей (на картинках показано как нужно разбить). В каждой части подсчитать количество черных пикселей(какой процент черных пикселей приходится на эту область). и вывести на экран. Подскажите пожалуйста джуниору как разбить изображение таким образом. Буду очень благодарен любой помощи.
Миниатюры
Разбить изображения на 20 ровных сектора и подсчитать количество черных пикселов в каждом из найденых секторов  
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.03.2015, 09:41
Ответы с готовыми решениями:

Переназначенные сектора, нестабильные сектора и неисправимые ошибки секторов
Решил я как то проверить с помощью Crystal Disk Info и на те сразу три ошибки. Насколько это опасно и можно ли их исправить?

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

Разбить область на сектора. Цвет нарисованной линии должен зависеть от сектора
Форма делится на сектора (их количество задает пользователь). Курсором мыши можно рисовать линии. Цвет линии зависит от сектора. При...

34
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
06.04.2015, 18:13
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от dexter007 Посмотреть сообщение
сделал. не помогло.
Я конечно сейчас бы ссаркастировал по поводу обширного описания результатов, но не буду.
Объясните пожалуйста более развернуто. Что именно произошло и что должно было. Потому как у меня вроде все ништяк.
0
 Аватар для dexter007
4 / 4 / 0
Регистрация: 10.10.2012
Сообщений: 27
07.04.2015, 10:13  [ТС]
видно я вас не правильно понял. вот код, в котором я написал комментарии. скажите пожалуйста в чем я ошибаюсь и что нужно изменить. (Задача: разбить изображение, чтобы начало координат былo в точке (0, 0))
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Memo1->Clear();
 
TRect Rect( 0, 0, Image1->Width, Image1->Height );
  int n = 20;
  unsigned int w = Image1->Width, h = Image1->Height;
  unsigned int max = w > h ? w : h;
  Image1->Canvas->Pen->Color = clRed;
  for( double count = 0; count <= 5; count+=5./n ) //просто изображение линий
    {
    Image1->Canvas->MoveTo( w/2, h/2 ); //почему "Соответственно нули"????
    Image1->Canvas->LineTo( w/2 + max * cos(2*M_PI*count/n), h/2 + max * sin(2*M_PI*count/n) );
    }
 
 
 
int *ArrTriangle = new int[n];
memset( ArrTriangle, 0, n*sizeof( int ) );
 
const TColor ColorFont = clBlack,
             ColorBack = clWhite;
 
for( unsigned int x = 0; x<w;  x++ )
  for( unsigned int y = 0; y<h; y++ )
    if( GetPixel( Image1->Canvas->Handle, x, y ) == ColorFont )
      for( unsigned int i = 0; i < n; i++ ) // или вы имели в виду этот цикл нужно изменить на 
 //for( double count = 0; count <= 5; count+=5./n ) ???
        {
 
        int x_center = 0,   // начало координат                            
            y_center = 0,   //                                
            x_angle = max * cos( 2*M_PI*i/n ),   // конечная точка вектора х       
            y_angle = max * sin( 2*M_PI*i/n ),   //конечная точка вектора y       
            x_curr = x,                                       
            y_curr = y;                                    
        int D1 = (x_curr - x_center) * (y_angle - y_center) - (y_curr - y_center) * (x_angle - x_center);
                                                                
        int x_next_angle = w + max * cos( 2*M_PI*(i+1)/n ),//следующая координата вектора х
            y_next_angle = h + max * sin( 2*M_PI*(i+1)/n );//следующая координата вектора y
 
        int D2 = (x_curr - x_center) * (y_next_angle - y_center) - (y_curr - y_center) * (x_next_angle - x_center);
 
 
        if( D1 >= 0 && D2 < 0 )
          ArrTriangle[i]++;
 
        }
 
int summ(0);
for(  int i = 0; i < n; i++ )
  {
  summ += ArrTriangle[i];
  Memo1->Lines->Add( ArrTriangle[i] );
  }
Memo1->Lines->Add( "-----------" );
Memo1->Lines->Add( summ );
}
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
07.04.2015, 11:22
Цитата Сообщение от dexter007 Посмотреть сообщение
//просто изображение линий
Именно. К расчету цикл не имеет никакого отношения. По хорошему следовало б их объединить. Разнесены для наглядности были.
Цитата Сообщение от dexter007 Посмотреть сообщение
//почему "Соответственно нули"?
Чтобы сместить разбиение на сектора в правый верхний угол. Если оставить координаты центра изображения и при этом поменять в цикле максимальное значение на магическую цифру пять, то вы должны были наблюдать, как только правая нижняя четверть изображения разобьется линиями.
Цитата Сообщение от dexter007 Посмотреть сообщение
// или вы имели в виду этот цикл нужно изменить
Да. И его тоже. Верхний только рисует, этот только считает. Соответственно оба должны быть одинаковыми.
0
 Аватар для dexter007
4 / 4 / 0
Регистрация: 10.10.2012
Сообщений: 27
07.04.2015, 11:27  [ТС]
Если оставить координаты центра изображения и при этом поменять в цикле максимальное значение на магическую цифру пять, то вы должны были наблюдать, как только правая нижняя четверть изображения разобьется линиями.
Так и есть.
Миниатюры
Разбить изображения на 20 ровных сектора и подсчитать количество черных пикселов в каждом из найденых секторов  
0
 Аватар для dexter007
4 / 4 / 0
Регистрация: 10.10.2012
Сообщений: 27
07.04.2015, 11:29  [ТС]
но должно быть так: https://www.cyberforum.ru/atta... 1428235482 . (Ну и значение в массиве должно быть другим)
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
07.04.2015, 12:01
Цитата Сообщение от dexter007 Посмотреть сообщение
но должно быть так
Соответственно вот здесь нули пропишите и сделайте еще один скриншот:
Цитата Сообщение от dexter007 Посмотреть сообщение
Image1->Canvas->MoveTo( w/2, h/2 ); //почему "Соответственно нули"????
0
 Аватар для dexter007
4 / 4 / 0
Регистрация: 10.10.2012
Сообщений: 27
07.04.2015, 12:04  [ТС]
вот
Миниатюры
Разбить изображения на 20 ровных сектора и подсчитать количество черных пикселов в каждом из найденых секторов  
1
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
07.04.2015, 13:00
Цитата Сообщение от dexter007 Посмотреть сообщение
вот
О, блин. Точно. Хи-хи-хи-хи-хи.

Ну покурите коэффициенты конечных точек отрезков. Подумайте как описать дугу.
0
 Аватар для dexter007
4 / 4 / 0
Регистрация: 10.10.2012
Сообщений: 27
07.04.2015, 18:26  [ТС]
дугу? зачем?
0
place status here
 Аватар для gunslinger
3192 / 2227 / 640
Регистрация: 20.07.2013
Сообщений: 6,028
08.04.2015, 12:25
Возможно, под дугой имелся в виду сектор (читай, треугольник, если придираться к формулировке). Других вариантов просто не вижу.
1
place status here
 Аватар для gunslinger
3192 / 2227 / 640
Регистрация: 20.07.2013
Сообщений: 6,028
08.04.2015, 15:42
Лучший ответ Сообщение было отмечено BRcr как решение

Решение

Сил моих больше нет. Ну это простейшая геометрия (максимум класс 7-ой школы).
Разбиение на сектора в случае расположения начальной точки в левом верхнем углу (лишнее выбросишь):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  const n = 20;
  Word i, j, line_length, w = Image1->Width, h = Image1->Height, l = Left + Image1->Left, t = Top + Image1->Top;
  Word border = (Width-ClientWidth)/2, topborder = Height-ClientHeight-border;
 
  Image1->Canvas->Pen->Color = clRed;
  for (i = 0; i <= n; i++)
  {
    Image1->Canvas->MoveTo(0, 0);
    line_length = w * tan(M_PI/2*i/n);
    if (line_length <= h)
      Image1->Canvas->LineTo(w, line_length);
    else
    {
      line_length = h * tan(M_PI/2*(1-1.*i/n));
      Image1->Canvas->LineTo(line_length, h);
    }
  }
Важно то, что не выходим за границы Image - при создании регионов и дальнейшем подсчете точек это ключевой момент.
Соответственно, отрисовку "лучей" не используем в итоге - нужна она лишь (как всегда) для визуального понимания.



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

Название: 583209bf6f11083b54edb5980bcfeeaa.jpg
Просмотров: 92

Размер: 1.9 Кб

Полный код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  const n = 20;
  Word i, j, line_length, w = Image1->Width, h = Image1->Height, l = Left + Image1->Left, t = Top + Image1->Top;
  Word border = (Width-ClientWidth)/2, topborder = Height-ClientHeight-border;
 
/*
  Image1->Canvas->Pen->Color = clRed;
  for (i = 0; i <= n; i++)
  {
    Image1->Canvas->MoveTo(0, 0);
    line_length = w * tan(M_PI/2*i/n);
    if (line_length <= h)
      Image1->Canvas->LineTo(w, line_length);
    else
    {
      line_length = h * tan(M_PI/2*(1-1.*i/n));
      Image1->Canvas->LineTo(line_length, h);
    }
  }
*/
 
  HRGN region[n];
  TPoint points[3];
  points[0] = Point(l + border, t + topborder);
  for (i = 0; i < n; i++)
  {
    for (j = 0; j <= 1; j++)
    {
      line_length = w * tan(M_PI/2*(i+j)/n);
      if (line_length <= h)
        points[j+1] = Point(l + border + w, t + topborder + line_length);
      else
      {
        line_length = h * tan(M_PI/2*(1-1.*(i+j)/n));
        points[j+1] = Point(l + border + line_length, t + topborder + h);
      }
    }
    region[i] = CreatePolygonRgn(points, 3, ALTERNATE);  // or WINDING ??  as u want
  }
 
/*
  for (i = 0; i < n; i++)
  {
    PaintRgn(GetDC(0), region[i]);  // отрисовка регионов (для проверки расположения областей)
  }
*/
 
  Byte k;
  unsigned __int64 point_count[n] = {0}, points_count = 0;
  for(j = 0; j < h; j++)
    for (i = 0; i < w; i++)
      if (Image1->Canvas->Pixels[i][j] == clBlack)
      {
        points_count++;
        for (k = 0; k < n; k++)
          if (PtInRegion(region[k], l + border + i, t + topborder + j))
            point_count[k]++;
      }
 
  String res = "Регион: кол-во черных пикселей\n";
  unsigned __int64 sum = 0;
  for (i = 0; i < n; i++)
  {
    res += String(i+1) + ": " + String(point_count[i]) + "\n";
    sum += point_count[i];
  }
  ShowMessage(res + "Всего черных пикселей: " + String(points_count) + " (проверка: " + String(sum) + ").");
 
  for (i = 0; i < n; i++)
    DeleteObject(region[i]);
Результат:



P.S.: если будут еще вопросы - начну очень сильно материться и биться головой об стену (все это одновременно).
3
09.04.2015, 15:05

Не по теме:

Цитата Сообщение от gunslinger Посмотреть сообщение
P.S.: если будут еще вопросы - начну очень сильно материться и биться головой об стену (все это одновременно).
Можно потом видео данного мероприятия? Пожалуйста?:D

0
09.04.2015, 21:36

Не по теме:

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

0
0 / 1 / 0
Регистрация: 07.05.2020
Сообщений: 129
20.10.2021, 23:37
gunslinger, можете подсказать, что делать если есть срез?
0
place status here
 Аватар для gunslinger
3192 / 2227 / 640
Регистрация: 20.07.2013
Сообщений: 6,028
21.10.2021, 01:55
Я уже не помню, давно было. И в коде это вроде у меня не сохранилось (если даже было сделано, в чем не уверен).
Что есть - ничем (похоже) не отличается от имеющегося, включая дату изменения. Поэтому помочь вряд ли смогу.

старый код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
Graphics::TBitmap *pBitmap;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  const n = 20;
  Word i, j, line_length, w = Image1->Width, h = Image1->Height, l = Left + Image1->Left, t = Top + Image1->Top;
  Word border = (Width-ClientWidth)/2, topborder = Height-ClientHeight-border;
 
/*
  Image1->Canvas->Pen->Color = clRed;
  for (i = 0; i <= n; i++)
  {
    Image1->Canvas->MoveTo(0, 0);
    line_length = w * tan(M_PI/2*i/n);
    if (line_length <= h)
      Image1->Canvas->LineTo(w, line_length);
    else
    {
      line_length = h * tan(M_PI/2*(1-1.*i/n));
      Image1->Canvas->LineTo(line_length, h);
    }
  }
*/
 
  HRGN region[n];
  TPoint points[3];
  points[0] = Point(l + border, t + topborder);
  for (i = 0; i < n; i++)
  {
    for (j = 0; j <= 1; j++)
    {
      line_length = w * tan(M_PI/2*(i+j)/n);
      if (line_length <= h)
        points[j+1] = Point(l + border + w, t + topborder + line_length);
      else
      {
        line_length = h * tan(M_PI/2*(1-1.*(i+j)/n));
        points[j+1] = Point(l + border + line_length, t + topborder + h);
      }
    }
    region[i] = CreatePolygonRgn(points, 3, ALTERNATE);  // or WINDING ??  as u want
  }
 
/*
  for (i = 0; i < n; i++)
  {
    PaintRgn(GetDC(0), region[i]);  // отрисовка регионов (для проверки расположения областей)
  }
*/
 
  Byte k;
  unsigned __int64 point_count[n] = {0}, points_count = 0;
  for(j = 0; j < h; j++)
    for (i = 0; i < w; i++)
      if (Image1->Canvas->Pixels[i][j] == clBlack)
      {
        points_count++;
        for (k = 0; k < n; k++)
          if (PtInRegion(region[k], l + border + i, t + topborder + j))
            point_count[k]++;
      }
 
  String res = "Регион: кол-во черных пикселей\n";
  unsigned __int64 sum = 0;
  for (i = 0; i < n; i++)
  {
    res += String(i+1) + ": " + String(point_count[i]) + "\n";
    sum += point_count[i];
  }
  ShowMessage(res + "Всего черных пикселей: " + String(points_count) + " (проверка: " + String(sum) + ").");
 
  for (i = 0; i < n; i++)
    DeleteObject(region[i]);
}
//---------------------------------------------------------------------------
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.10.2021, 01:55

Подсчитать количество черных пикселей на Picturebox
написал код который должен считать количество черных пикселей на картинке, загруженной в picturebox. Сама картинка из paint черно-белая на...

Нестабильные сектора и Неисправимые ошибки секторов
Всем привет, хотелось бы узнать, если ли причины для тревоги? Сколько такой диск может ещё прожить? ...

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

Неполадки с HDD: нестабильные сектора и неисправимые ошибки секторов
Здравствуйте, прошу помощи в определении причин неисправности. Имеются 2 диска: 1- ST1000DL002 1000gb, работает 7-ой год как часы, 2 -...

Запись в сектора на floppy-диске, и чтение с этих секторов
Здраствуйте. Меня интерисует Функция на Си чтоби записывать данные (строку, или часть отдельного файла) в отдельный сектор на флопи...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Опции темы

Новые блоги и статьи
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru