Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Как перевести рисунок-квадрат в матрицу и прочее


Автор: Scherhan 31.10.2002, 06:57
Привет, всем!
У меня на Билдере написана прога: На одной форме сделаны два окна (обозначим: А и Б). В окне_А нах-ся Image_1, а в окне_Б - Image_2, с одинаковым рисунком в каждом Image. Поверх Image_1 и Image_2 установлены PaintBox(рисуем на нем). В окне_1 кликом мыши рисуется квадрат 24х24 (Rectangle(X0,Y0,X0+24,Y+24)), а в окне_2, также кликом мыши рисуется квадрат 96х96(Rectangle(X0,Y0,X0+96,Y+96)). Нужно перевести квадрат в матрицу: для кв-та 24х24 - Matrix_A[][] и для кв-та 96х96 - Matrix_B[][]:
Вот отрывок: //----------------------------------------------------------------//
const int num_rows1 = 24;
const int num_cols1 = 24;
const int num_rows2 = 96;
const int num_cols2 = 96;
int Matrix_A[num_rows1][num_cols1];
int Matrix_B[num_rows2][num_cols2];
int col1,col2,row1,row2;

for (col1 = 0; col1 < num_cols1; col1++)
for (row1 = 0; row1 < num_rows1; row1++)
{
 Matrix_A[row1][col1] = ((Y0+row1),(X0+col1));
 Matrix_A[num_rows1][num_cols1] = Matrix_A[row1][col1];
}

for (col2 = 0; col2 < num_cols2; col2++)
for (row2 = 0; row2 < num_rows2; row2++)
{
 Matrix_B[row2][col2] = ((Y0+row2),(X0+col2));
 Matrix_B[num_rows2][num_cols2] = Matrix_A[row2][col2];
}
//----------------------------------------------------------------//

Скажите, пожалуйста, правильно написала "перевод" координат квадратов в матрицы?

Вот моя проблема: Нужно сделать, чтобы в окне_2,в квадрате 96х96 искался квадрат 24х24, путём построчного поиска в матрице (Matrix_B) до его нахождения. Как я поняла, берётся квадрат 24х24 и ищем его в квадрате 96х96 т.о.: начиная с первой точки квадрата 96х96, ищется построчно через один пиксел матрицы (Matrix_B) и до конца этой матрицы. Если нашёлся в квадрате 96х96, то в нём рисуется квадрат 24х24, а иначе-выдать сообщение.
Ну, не знаю, как это сделать...помогите, пожалуйста!!!

Спасибо за то, что уделили мне внимание. Пока.

Автор: Baa 31.10.2002, 08:20
Так... по порядку... в чем проблема? в том, чтобы составить алгоритм поиска или в том, как загнать кусок рисунка в матрицу?

Автор: Scherhan 31.10.2002, 16:30
Привет, Baa!
Хотелось-бы, и то и другое...Пожалуйста :)
Спасибо за отклик.

Автор: Baa 1.11.2002, 00:06
Так...ну для начала тема тебе для размышления...
Чтобы загнать цвета рисунка в матрицу надо пройтись по ней с помощью GetPixel...
Первый параметр там вроде должен быть Image->Picture->Bitmap->Canvas->Handle
з.ы. этого я точно не помню, потому как билдер не использую.
з.з.ы. надеюсь прогнать GetPixel ты сумеешь.
И вот ты загоняешь два рисунка в матрицы.
Допустим с этим управились.
Далее получаем квадратную область от мышки.
Делаем еще одну матрицу и запихиваем туда фрагмент первой картинки.
Надеюсь выбрать фрагмент со смещением не вызовет затруднений.
То же самое делаем со вторым рисунком и еще одной матрицей.
А потом уже делаем поиск.
Поиск...как мне кажется, поиск лучше делать по первому столбцу и колонке. Если будет достигнуто совпадение, то тогда уже делать дальнейшее сравнение.

Автор: Baa 5.11.2002, 07:34
Если кого интересует, то на скорую руку это решается так:
Код

void CBitmapDlg::OnBnClickedButton1()
{
iMatrix1 = new COLORREF [256*256];
iMatrix2 = new COLORREF [256*256];
SendDlgItemMessage (IDC_PROGRESS1, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
SendDlgItemMessage (IDC_PROGRESS2, PBM_SETRANGE, 0, MAKELPARAM(0, 100));

SendDlgItemMessage (IDC_PROGRESS1, PBM_SETSTEP, (WPARAM)1, 0);
SendDlgItemMessage (IDC_PROGRESS2, PBM_SETSTEP, (WPARAM)1, 0);

SendDlgItemMessage (IDC_PROGRESS1, PBM_SETPOS, 0, 0);
SendDlgItemMessage (IDC_PROGRESS2, PBM_SETPOS, 0, 0);

static int iTempProgress = 0;

HBITMAP hBitmap = LoadBitmap (AfxGetApp ()->m_hInstance, MAKEINTRESOURCE (IDB_BITMAP1));
if (!hBitmap) AfxMessageBox ("Failed to load image");
HWND hWnd = GetDlgItem (IDC_STATIC1)->m_hWnd;
HDC hdc = ::GetDC (hWnd);
HDC mdc = ::CreateCompatibleDC (hdc);
SelectObject (mdc, hBitmap);
BitBlt (hdc, 0, 0, 256, 256, mdc, 0, 0, SRCCOPY);
iTempProgress = 0;
for (int i = 0; i < 256; i++)
for (int j = 0; j < 256; j++)
{
           iMatrix1[i*256+j] = GetPixel (hdc, i, j);
iTempProgress++;
SendDlgItemMessage (IDC_PROGRESS1, PBM_SETPOS, (WPARAM)((100*iTempProgress)/(256*256)), 0);
}
AfxMessageBox ("First Matrix Loaded");
::ReleaseDC (hWnd, hdc);
hWnd = GetDlgItem (IDC_STATIC2)->m_hWnd;
hdc = ::GetDC (hWnd);
SelectObject (mdc, hBitmap);
BitBlt (hdc, 0, 0, 256, 256, mdc, 0, 0, SRCCOPY);
iTempProgress = 0;
for (int i = 0; i < 256; i++)
for (int j = 0; j < 256; j++)
{
           iMatrix2[i*256+j] = GetPixel (hdc, i, j);
iTempProgress++;
SendDlgItemMessage (IDC_PROGRESS2, PBM_SETPOS, (WPARAM)((100*iTempProgress)/(256*256)), 0);
}
AfxMessageBox ("Second Matrix Loaded");
::ReleaseDC (hWnd, hdc);
DeleteObject (hBitmap);
DeleteDC (mdc);
GetDlgItem (IDC_BUTTON2)->EnableWindow (true);
}

int CompareMatrix (COLORREF* lpMatrix1, COLORREF* lpMatrix2, POINT* lpPoint1, POINT* lpPoint2)
{
COLORREF ilMatrix1[96][96];
COLORREF ilMatrix2[24][24];
for (int i = 0; i < 96; i++)
for (int j = 0; j < 96; j++)
ilMatrix1[i][j] = lpMatrix1[(i+lpPoint1->x)*256+j+lpPoint1->y];
for (int i = 0; i < 24; i++)
for (int j = 0; j < 24; j++)
ilMatrix2[i][j] = lpMatrix2[(i+lpPoint2->x)*256+j+lpPoint2->y];
bool bFlag = false;
for (int i = 0; i < 96 - 24; i++)
for (int j = 0; j < 96 - 24; j++)
{
for (int m = 0; m < 24; m++)
{
for (int k = 0; k < 24; k++)
if (ilMatrix1[i+m][j+k] != ilMatrix2[m][k]) {
bFlag = false;
break;
} else bFlag = true;
if (!bFlag) break;
}
if (bFlag) return bFlag;
}
return bFlag;
}

void CBitmapDlg::OnBnClickedButton2()
{
POINT point1, point2;
point1.x = GetDlgItemInt (IDC_EDIT1);
point1.y = GetDlgItemInt (IDC_EDIT2);

point2.x = GetDlgItemInt (IDC_EDIT5);
point2.y = GetDlgItemInt (IDC_EDIT6);
CompareMatrix (iMatrix1, iMatrix2, &point1, &point2) ? AfxMessageBox ("Fragment Found") : AfxMessageBox ("Fragment Not Found");
}

void CBitmapDlg::OnBnClickedButton3()
{
delete [] iMatrix1;
delete [] iMatrix2;
GetDlgItem (IDC_BUTTON2)->EnableWindow (false);
SendDlgItemMessage (IDC_PROGRESS2, PBM_STEPIT, 0, 0);
}

void CBitmapDlg::OnDestroy()
{
OnBnClickedButton3 ();
}

Автор: Scherhan 17.11.2002, 10:49
Привет, Всем! Спасибо за помощь!!!
Прошу, извинить меня за неверное пояснение своей проблемы...Оказалось, что я, сама не поняла, что требовалось сделать 8-0 Вот более верное:
Даны два снимка в формате BMP: первый снимок имеет, например, размер 512х1024, а второй - 1200х2048. Каждый из них по содержанию, одинаков, но разница есть, например, первый - снят год назад, а второй - сегодня и ещё, снимок м.б. разного масштаба.
На первом снимке мышью выводим квадратик 24х24, а затем во втором - квадратик 96х96. Требуется: во втором снимке, в квадрате 96х96 найти ту область, кот. выбралась в первом снимке. Как я говорила, что надо перевести координаты квадрата 24х24, как и квадрат 96х96 в матрицы. А затем, во втором квадрате "по-пиксельно прогнать" первый квадрат. Трабла в том, как перевести координаты квадратика в матрицу и как учесть разницу в масштабах...???? Помогите, пожалуйста. Спасибо.

Автор: Baa 17.11.2002, 11:11
Да собственно мало чем отличается... создаем в памяти контекст и на нем увеличиваем масштаб первого квадрата, а далее ищем его во втором.

Автор: Scherhan 17.11.2002, 12:44
Привет, Ваа!
Тебе не будет трудно, мне пояснить, более яснее...а то не врубаюсь%) Ну, понимаешь, недавно начала программировать...пока, этакий чайничек :)
Пока и Спасибо!!!

Автор: Baa 18.11.2002, 10:48
Поясняю... хотя может этого будет мало :\
Есть у нас первая картинка (кстати, увеличение идет вдвое или размеры второй картинки не опечатка? )
Мы на ней выбрали квадратик. Далее мы делаем невидимый клон этой картинки (т.е. ползователь её не видит) и массштабируем её до размеров второй картинки.
У нас получается две картинки с одинаковым масштабом. Соотв. квадратик тоже смасштабировался. Терь загоняем его в матрицу и ищем. Все. :)

Автор: Scherhan 19.11.2002, 05:16
Привет, Baa! Спасибо, что не забыл меня :)
Вообще, в двух окнах разные снимки. Например, фотографируем твой район: первый снимок  сделан 10 ноября прошлого года с самолёта, а второй снимок сделан 23 августа этого года со спутника. На первом снимке виден твой дом, а на втором - весь район. Вот...
Не пойму, как загнать квадрат в матрицу :(
Спасибо. Пока.

Автор: Baa 19.11.2002, 10:40
Билдера нет, а на пальцах походу не объяснишь :(
Эх, попробую по памяти...
Картинка сама по себе матрица.
Как обратиться к элементам (пикселям) картинки? очень просто
так кажется: Image1->Picture->Bitmap->Canvas->Pixels [0][0];
В цикле загоняешь нужное тебе кол-во элементов в матрицу и порядок.

Автор: Scherhan 21.11.2002, 04:52
Всё поняла, кроме "кол-во элементов в матрицу и порядок", т.е кол-во элементов - если квадрат размером 24x24, то всего 48 элементов???
Еще,вот нарисовала квадратик на снимке, координаты известны: левый верхний угол (Х0,Y0), нижний правый угол (Х0+24,Y0+24), а дальше что надо делать...Загнать Pixels [n][m], где n,m = 24 в матрицу?

Автор: Baa 21.11.2002, 05:02
Мда...
Пойми, Pixels[x,y] - это уже матрица... матрица рисунка... возвращает COLORREF если я не ошибаюсь.
Есть у тебя матрица COLORREF Matrix[24][24];
Вот в цикле заноси суда ту матрицу с нужной позиции.
Выделяем квадрат на картинке.
Начало его находится, допустим в x=7 y=20 соотв. конец его x+24 y+24
Терь тебе надо занести его в матрицу.
Matrix [0][0] = Pixels[x][y];
Matrix [0][1] = Pixels[x][y+1];
и т.д. пока не занесешь туда нужное количество значений.
делается это через цикл
for (int i = 0; i < 24; i++)
   for (int j = 0; j < 24; j++)
       Matrix [i][j] = Pixels [i+x] [j+y];

Автор: Scherhan 25.11.2002, 03:10
:) Я уже разобралась с этим, но твоё пояснение подтвердило верность моих суждений ;-) Спасибо.
Вопрос возникает в другом: создали две матрицы с пикселями. Далее, надо взять Matrix_1[0][0] прогнать построчно по Matrix_2[m][m] и т.д.,но ведь по пикселам не сравнишь :dg Значит, надо найти по цвету, по контуру или яркости??? Но как???

Автор: Baa 25.11.2002, 03:24
Ну вот, докатились... Извини, а чего мы в матрицу заносили?
Ведь мы цвет пикселя заносили-то...

Автор: Scherhan 26.11.2002, 07:40
Ваа, не сердись...Я ёще, только учусь...
Хорошо, определили цвета пикселей, а как их сравнивать между собой? Из первой матрицы беру первый пиксел "прогоняю" его по второй матрице, так ли??? Если, да, то как?
Спасибо.

Автор: Baa 28.11.2002, 09:10
Посмотри тот код, который я привел в начале... там все есть...

Автор: Alamo 28.11.2002, 17:11
Соблюдение масштаба - вещь хорошая, но без предположений реальный снимок не обработаешь

Автор: Scherhan 29.11.2002, 04:56
Ваа, спасибо :)))

Привет, Аламо!
>Соблюдение масштаба - вещь хорошая, но без предположений реальный >снимок не обработаешь
Что ты под этим подразумеваешь? Какие предположения?

Автор: Baa 29.11.2002, 07:56
Он прав, если фотки разные, то прямым поиском ничего не добьешься...
Такое можно вытворять только с идентичными фотками, только в разных масштабах...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)