LINUX.ORG.RU

CvMat выбрать значения


0

1

Есть картинка image, она в градациях серого. Получаю матрицу нужной области из неё с помощью:

CvMat data;
cvGetSubRect(image, &data, rect);
Если выполнить
cvSave(buf, &data);
то в xml файле будет матрица состоящая из значений 255 и 0. Что мне и нужно. Только мне нужно получить эти значения в обычный двумерный массив int **matrix без использования записи в файл. Проблема в том, что в data.data хранятся не 255 и 0, а другие значения, просто cvSave как-то выбирает нужный формат, наверное Indexed8. (Не знаю матчасть.)

Я могу вывести картинку, полученную из этой матрицы используя Indexed8:

cv::Mat m = cv::Mat(&data);
QImage q_image2 = mat_to_qimage_ref(m, QImage::Format_Indexed8);
label_2->setPixmap(QPixmap::fromImage(q_image2.rgbSwapped()));

А если заменить Indexed8 на RGB, то область уменьшится в 3 раза и склонируется 3 раза.

В этом и прикол, что когда я вывожу значения из матрицы в TextEdit

 QTextCursor cursor = ui->textEdit->textCursor();
                    for (int i = 0; i < data.rows; ++i) {
                        int* ptr = (int*)(data.data.ptr + i*data.step);
                        for (int j = 0; j < data.cols; ++j) {
                            if (ptr[j] == 0)
                                cursor.insertText(QString::number(0));
                            else
                                cursor.insertText(QString::number(1));
                        }
                        cursor.insertText("\n");
                     }
То получаю клонированную область. Т.е. допустим в области у меня находилась звездочка. Вместо нарисованной звездочки нулями и единицами в TextEdit я получу 3 уменьшенные звездочки. Потому что данные хранятся в CvMat не в формате Indexed8. Так как мне вывести так, чтобы была одна звездочка. Или как получить из CvMat двумерный массив int** в котором бы хранились только значеня 255 и 0. Попытался объяснить проблему по максимуму, но наверное только больше запутал. Помогите в общем пожалуйста.


Т.е. data у меня сейчас трехканальный, а его нужно, наверное, сделать одноканальным.

mrXorg
() автор топика
Ответ на: комментарий от yoghurt

int** ты (скорее всего) не получишь просто так, потому что внутри cv::Mat данные (скорее всего) хранит в обычном массиве (не вложенном).

Вы путаете CvMat с cv:Mat

В градациях серого и трехканальный?

Картинка в градациях серого. Но CvMat же об этом не знает...

mrXorg
() автор топика
Ответ на: комментарий от yoghurt

У CvMat-а потроха тоже документированы, разве нет?

Переформулируйте пожалуйста вопрос. Не понял что вы имеете в виду?

mrXorg
() автор топика
Ответ на: комментарий от yoghurt
IplImage *pic = cvLoadImage(FileOpName.toAscii().data());
            IplImage *gray_image = cvCreateImage(cvGetSize(pic), IPL_DEPTH_8U, 1);
            cvCvtColor(image, gray_image, CV_BGR2GRAY);
            // размытие
            IplImage *smooth_gray_image = cvCloneImage(gray_image);
            cvSmooth(gray_image, smooth_gray_image, CV_GAUSSIAN, 3);
            // порог
            CvScalar avg;       // среднее значение для массива, независимо от канала
            CvScalar avgStd;    // среднее отклонение для массива, независимо от канала
            cvAvgSdv(smooth_gray_image, &avg, &avgStd, NULL);

            IplImage *threshold_smooth_gray_image = cvCloneImage(gray_image);
            cvThreshold(smooth_gray_image, image,
                        (int)avg.val[0] - 7 * (int)(avgStd.val[0] / 8), 255, CV_THRESH_BINARY_INV);

Даже не знаю, сейчас попробую вывести, вот код, image получаю в последней строчке

mrXorg
() автор топика
Ответ на: комментарий от mrXorg

Блин, код криво переделал, просто я посылал не image а threshold_smooth_gray_image, вот код нормальный

 IplImage *image = cvLoadImage(FileOpName.toAscii().data());
            IplImage *gray_image = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
            cvCvtColor(image, gray_image, CV_BGR2GRAY);
            // размытие
            IplImage *smooth_gray_image = cvCloneImage(gray_image);
            cvSmooth(gray_image, smooth_gray_image, CV_GAUSSIAN, 3);
            // порог
            CvScalar avg;       // среднее значение для массива, независимо от канала
            CvScalar avgStd;    // среднее отклонение для массива, независимо от канала
            cvAvgSdv(smooth_gray_image, &avg, &avgStd, NULL);

            IplImage *threshold_smooth_gray_image = cvCloneImage(gray_image);
            cvThreshold(smooth_gray_image, threshold_smooth_gray_image,
                        (int)avg.val[0] - 7 * (int)(avgStd.val[0] / 8), 255, CV_THRESH_BINARY_INV);

т.е. делаю я cvGetSubRect(threshold_smooth_gray_image, &data, rect); на самом деле

mrXorg
() автор топика
Ответ на: комментарий от mrXorg
IplImage *pic = cvLoadImage(FileOpName.toAscii().data());
IplImage *gray_image = cvCreateImage(cvGetSize(pic), IPL_DEPTH_8U, 1);
cvCvtColor(image, gray_image, CV_BGR2GRAY);

Что-то в упор не вижу, где создается/инициализируется сам image.

Но если оно работает, image изначально, видимо, трехканальный

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

Что-то в упор не вижу, где создается/инициализируется сам image.

Криво переделал, посмотрите сообщение выше пожалуйста, исправил.

mrXorg
() автор топика
Ответ на: комментарий от mrXorg

Пока есть только извращенное решение, сохранять с помощью svSave в .xml, парсить оттуда данные, удалять .xml. Но это очень не хочется делать.

mrXorg
() автор топика
Ответ на: комментарий от mrXorg

И что у тебя в итоге оказывается в data? Там должно быть одноканальное изображение. Дамп можешь вывести текстовый?

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

Вот, на картинке была цифра 3, строк 33, столбцов 20

0-16777216-1000-256-1167772150-16777216-1-1-10-65536-1-1-165535
0-256-1167772150-16777216-1-1-10-65536-1-1-165535-256-1255-165535
-16777216-1-1-10-65536-1-1-165535-256-1255-165535-256167772150-25665535
-65536-1-1-165535-256-1255-165535-256167772150-25665535-1655350-1677721616777215
-256-1255-165535-256167772150-25665535-1655350-1677721616777215-12550-1677721616777215
-256167772150-25665535-1655350-1677721616777215-12550-1677721616777215000-1677721616777215
-1655350-1677721616777215-12550-1677721616777215000-1677721616777215000-16777216-1
-12550-1677721616777215000-1677721616777215000-16777216-1000-1677721616777215
000-1677721616777215000-16777216-1000-1677721616777215000-1677721616777215
000-16777216-1000-1677721616777215000-1677721616777215000-6553616777215
000-1677721616777215000-1677721616777215000-6553616777215000-25665535
000-1677721616777215000-6553616777215000-2566553500-1-165535
000-6553616777215000-2566553500-1-16553500-1-1255
000-2566553500-1-16553500-1-125500-1-1255
00-1-16553500-1-125500-1-125500-1-165535
00-1-125500-1-125500-1-165535000-165535
00-1-125500-1-165535000-165535000-6553616777215
00-1-165535000-165535000-6553616777215000-16777216-1
000-165535000-6553616777215000-16777216-1000-16777216-1
000-6553616777215000-16777216-1000-16777216-10000-1
000-16777216-1000-16777216-10000-10000-1
000-16777216-10000-10000-10000-1
0000-10000-10000-10000-1
0000-10000-10000-1-12550-16777216-1
0000-10000-1-12550-16777216-1-1655350-16777216-1
0000-1-12550-16777216-1-1655350-16777216-1-256167772150-25616777215
-12550-16777216-1-1655350-16777216-1-256167772150-25616777215-256-1-1-165535
-1655350-16777216-1-256167772150-25616777215-256-1-1-165535-16777216-1-1-165535
-256167772150-25616777215-256-1-1-165535-16777216-1-1-165535-16777216-1-1-1255
-256-1-1-165535-16777216-1-1-165535-16777216-1-1-12550-65536-1167772150
-16777216-1-1-165535-16777216-1-1-12550-65536-1167772150115274714433151721608150306184
-16777216-1-1-12550-65536-116777215011527471443315204625615199317600150366208032
0-65536-11677721501152747144331520475761517211443015265463226624032256152664344000
А если сделать замену всех цифр не равных 0 на 1, то получим клоны 3, плохо видно, но можно заметить
01100011101111011111
01110111101111111111
11110111111111111011
11111111111101111011
11111110111101111011
11011110111101100011
11011110110001100011
11011000110001100011
00011000110001100011
00011000110001100011
00011000110001100011
00011000110001100111
00011000110011100111
00011001110011100111
00111001110011100111
00111001110011100011
00111001110001100011
00111000110001100011
00011000110001100011
00011000110001100001
00011000110000100001
00011000010000100001
00001000010000100001
00001000010000111011
00001000011101111011
00001110111101111011
11011110111101111111
11011110111111111111
11011111111111111111
11111111111111101110
11111111110111011110
11111011101111011111
01110111101111110111
а такое в файле (как мне и надо)
00000001111100000000
00000111111111100000
00011111111111110000
00111111111111111100
01111111100011111100
01111110000001111100
11111100000000011110
11111000000000011110
00000000000000011110
00000000000000011111
00000000000000011110
00000000000000011110
00000000000000111110
00000000000001111100
00000000111111111100
00000000111111111000
00000000111111111000
00000000111111111100
00000000000011111100
00000000000000111110
00000000000000011111
00000000000000011111
00000000000000001111
00000000000000001111
00000000000000001111
00000000000000001111
11111000000000011111
11111100000000011111
01111110000001111110
01111111111111111100
00011111111111111100
00011111111111111000
00000011111111100000

mrXorg
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.