
- •Научно исследовательская работа студента На тему
- •Оглавление
- •Глоссарий
- •Введение
- •1.Цель и задачи
- •2.Предпроектное исследование
- •2.1 Анализ объектной среды
- •3.Концептуальная модель
- •4.Требования
- •4.1Название программы(модуля)
- •4.2 Функции программы(модуля)
- •4.7 Критерий качества системы.
- •5.Проектное решение
- •5.3Разработка структуры данных
- •6.Реализация
- •6.1 Реализация программы
- •7.Проведение эксперимента и тестирования системы
- •7.1 Тестирование системы
- •7.2 Эксперимент системы
- •1 Этап.
- •8. Заключение
- •Список литературы
- •Приложение а
8. Заключение
В ходе проделанной работы был создан модуль построения матрицы пространственной смежности. Как показало тестирование, на данный момент происходит построение матрицы смежности по клетки крови, в результате которой рассчитываются получаемые признаки.
Работа состоит из четырех частей.
В анализе предметной области были рассмотрены общие положения: определение текстур, построение матрицы смежности.
В анализе объектной среды были выдвинуты требования к обрабатываемым изображениям.
В разработке требований к проведению эксперимента были прописаны исходные условия, требования к вычислительной технике, программному обеспечению. Также был разработан критерий качества системы и концептуальная модель программы.
Был реализован интерфейс программы.
Для тестирования работоспособности программы был проведен эксперимент. Были поставлена цель и задачи эксперимента. В ходе эксперимента, были построены матрицы смежности для 2 типов клеток(лимфоцит (10), базофил(10) по котором рассчитаны признаки. Результаты эксперимента были занесены в таблицу. На основе таблиц были сделаны выводы о признаках посчитанные для этих видов клеток, как показали результаты, оптимальными признаками для распознавания клеток крови являются: "момент инерции", "энтропия" и "локальная однородность".
Список литературы
1)Под редакции В.А.Сойфера «Методы компьютерной обработки изображений»
2)Б.Яне «Цифровая обработка изображений
3) Прэтт У. Цифровая обработка изображений: В 2 кн. – М. : Мир, 1982.
4) Гонсалес Р., Вудс Р. Цифровая обработка изображений. – М. : Техносфера, 2005. – 1070 с.
5) Прэтт У., Цифровая обработка изображений. – М.: Мир, 1982. – Кн. 2 – 480 с.
6) http://ru.wikipedia.org
7) http://logic.pdmi.ras.ru/csclub/en/node/295
8) Анисимов Б.В., Курганов В.Д., Злобин В.К. Распознавание и цифровая обработка изображений.1983
9) Обработка изображения, распознавание образов, мультимедиа
10) Токарев ДВ Библиотека Кашкина ЛВ Кашкин ВБ Рублева ТВ Шикунова ОА Цифровая обработка изображений
11) Павлидис Т. Алгоритмы машинной графики и обработки изображений. – М. : Радио и связь, 1986. – 400 с.
12) http://www.st-s.su/sites/default/files/files/pdf/2011-45/2011-45-danilov.pdf
Приложение а
#include "stdafx.h"
using namespace lyr;
TLayer32 matrix_lay;
void nucl_finder(const TLayer32& cell, TLayer32& dest, int range)
{
for(size_t x = 0; x < cell.W; ++x)
for(size_t y = 0; y < cell.H; ++y)
{
pix32 p = cell(x,y);
if((p.comp[r_rgb] + p.comp[g_rgb] + p.comp[b_rgb]) < range)
{
p.comp[r_rgb] = 255;
}
else
{
p.comp[r_rgb] = 0;
}
dest(x,y) = p;
}
}
void draw_area(lyr::TLayer32& dest, int x1, int y1, int x2, int y2)
{
pix32 p;
p.comp[r_rgb] = 128;
p.comp[g_rgb] = 0;
p.comp[b_rgb] = 128;
if(x1 > x2)
{
x2 += x1;
x1 = x2 - x1;
x2 = x2 - x1;
}
if(y1 > y2)
{
y2 += y1;
y1 = y2 - y1;
y2 = y2 - y1;
}
if(x1 < 0)
x1 = 0;
if(x2 > dest.W)
x2 = dest.W;
if(y1 < 0)
y1 = 0;
if(y2 > dest.H)
y2 = dest.H;
for(int i = x1; i < x2; ++i)
{
dest(i,y1) = p;
dest(i,y2) = p;
dest(i,y1+1) = p;
dest(i,y2-1) = p;
}
for(int i = y1; i < y2; ++i)
{
dest(x1,i) = p;
dest(x2,i) = p;
dest(x1+1,i) = p;
dest(x2-1,i) = p;
}
}
void RGBtoCMYK(const pix32& src, int (&dest)[3])
{
float c,m,y,k;
k = 1;
c = (255 - (float)src.comp[r_rgb]) / 255;
if(c < k)
k = c;
m = (255 - (float)src.comp[g_rgb]) / 255;
if(m < k)
k = m;
y = (255 - (float)src.comp[b_rgb]) / 255;
if(y < k)
k = y;
if(k == 1)
{
c = 0;
m = 0;
y = 0;
}
else
{
c = (c - k)/(1 - k);
m = (m - k)/(1 - k);
y = (y - k)/(1 - k);
}
dest[0] = c * 255;
dest[1] = m * 255;
dest[2] = y * 255;
}
void RGBtoLab(const pix32& src, int (&dest)[3])
{
double Rn, Gn, Bn, x, y, z;
Rn = (double)src.comp[r_rgb] / 255;
Gn = (double)src.comp[g_rgb] / 255;
Bn = (double)src.comp[b_rgb] / 255;
if (Rn > 0.04045)
Rn = pow(((Rn + 0.055) / 1.055),2.4);
else
Rn = Rn / 12.92;
if (Gn > 0.04045)
Gn = pow(((Gn + 0.055) / 1.055),2.4);
else
Gn = Gn / 12.92;
if (Bn > 0.04045)
Bn = pow(((Bn + 0.055) / 1.055),2.4);
else
Bn = Bn / 12.92;
Rn = Rn * 100;
Gn = Gn * 100;
Bn = Bn * 100;
x = Rn * 0.4124 + Gn * 0.3576 + Bn * 0.1805;
y = Rn * 0.2126 + Gn * 0.7152 + Bn * 0.0722;
z = Rn * 0.0193 + Gn * 0.1192 + Bn * 0.9505;
x = x / 95.047;
y = y / 100.000;
z = z / 108.883;
double div = 1.0 / 3.0;
if (x > 0.008856)
x = pow(x, div);
else
x = (7.787 * x) + (16/116);
if (y > 0.008856)
y = pow(y, div);
else
y = (7.787 * y) + (16/116);
if (z > 0.008856)
z = pow(z, div);
else
z = (7.787 * z) + (16/116);
double L,a,b;
L = (116 * y) - 16;
a = 500 * (x - y);
b = 200 * (y - z);
if(L < 0)
dest[0] = L * (-2.55);
else
dest[0] = L * 2.55;
dest[1] = 128 + a;
dest[2] = 128 + b;
}
//функция рассчёта матриц для двух соседних пикселей
void matrix_count(const pix32& p1, const pix32& p2, float (&matr_r)[256][256], float (&matr_g)[256][256], float (&matr_b)[256][256], float (&matr_c)[256][256], float (&matr_m)[256][256], float (&matr_y)[256][256], float (&matr_L)[256][256], float (&matr_La)[256][256], float (&matr_Lb)[256][256])
{
//массивы для хранения CMYK и Lab компонент
int CMYK1[3], CMYK2[3], Lab1[3], Lab2[3];
//преобразование цветов для обоих обрабатываемых пикселей
RGBtoCMYK(p1, CMYK1);
RGBtoCMYK(p2, CMYK2);
RGBtoLab(p1, Lab1);
RGBtoLab(p2, Lab2);
//рассчитываем матрицу для каждой из цветовых компонент
component_count(p1.comp[r_rgb],p2.comp[r_rgb],matr_r);
component_count(p1.comp[g_rgb],p2.comp[g_rgb],matr_g);
component_count(p1.comp[b_rgb],p2.comp[b_rgb],matr_b);
component_count(CMYK1[0],CMYK2[0],matr_c);
component_count(CMYK1[1],CMYK2[1],matr_m);
component_count(CMYK1[2],CMYK2[2],matr_y);
component_count(Lab1[0],Lab2[0],matr_L);
component_count(Lab1[1],Lab2[1],matr_La);
component_count(Lab1[2],Lab2[2],matr_Lb);
}
//рассчёт матрицы по одной из компонент
void component_count(size_t p1, size_t p2, float (&matr)[256][256])
{
++matr[p1][p2];
if (p1 != p2)
++matr[p2][p1];
}
//рассчёт свойств по матрице
void property_count(float (&matr)[256][256], float (&props)[5])
{
//находим сумму всех элементов матрицы
size_t summ = 0;
for(size_t i = 0; i < 256; ++i)
for(size_t j = 0; j < 256; ++j)
{
summ += matr[i][j];
}
//и нормируем её
for(size_t i = 0; i < 256; ++i)
for(size_t j = 0; j < 256; ++j)
{
matr[i][j] = matr[i][j] / summ;
}
//находим непосредственно свойства
for(size_t i = 0; i < 256; ++i)
for(size_t j = 0; j < 256; ++j)
{
//энергия
props[0] += matr[i][j] * matr[i][j];
//момент инерции
props[1] += (i - j) * (i - j) * matr[i][j];
//энтропия
if(matr[i][j])
props[2] += matr[i][j] * log(matr[i][j]) * (-1);
//локальная неоднородность
props[3] += matr[i][j] / (1 + (i - j) * (i - j));
//максимальная вероятность
if(props[4] < matr[i][j])
props[4] = matr[i][j];
}
}
//основная функция построения матриц и рассчёта свойств
void matrix_build(const TLayer32& src, TLayer32& nucl, size_t x1, size_t x2, size_t y1, size_t y2, float (&matr_r)[256][256], float (&matr_g)[256][256], float (&matr_b)[256][256], float (&matr_c)[256][256], float (&matr_m)[256][256], float (&matr_y)[256][256], float (&matr_L)[256][256], float (&matr_La)[256][256], float (&matr_Lb)[256][256], cell_prop &props, bool mode)
{
//обходим картинку для собственно расчета матрицы смежности,
//х1, х2, у1 и у2 - границы выделенной области, при отсутствие
//выделения совпадающие с границами картинки
nucl_finder(src, nucl, 450);
for(size_t y = y1; y < y2; ++y)
{
for(size_t x = x1; x < x2; ++x)
{
//текущий пиксель
pix32 curr = nucl(x,y);
//при потоковой обработке обрабатываем лишь автоматически выделенное ядро
if (mode || curr.comp[r_rgb])
{
curr = src(x,y);
//условие существования левого нижнего пикселя(не первый столбец и не последняя строка)
if ((x != x1) && (y != (y2 - 1)))
{
pix32 leftbott = src(x-1,y+1);
//рассчёт матриц для этих двух пикселей
matrix_count(curr, leftbott, matr_r, matr_g, matr_b, matr_c, matr_m, matr_y, matr_L, matr_La, matr_Lb);
}
//условие существования нижнего пикселя(не последняя строка)
if (y != (y2 - 1))
{
pix32 bott = src(x, y+1);
//рассчёт матриц для этих двух пикселей
matrix_count(curr, bott, matr_r, matr_g, matr_b, matr_c, matr_m, matr_y, matr_L, matr_La, matr_Lb);
}
//условие существования правого нижнего пикселя(не последние столбец или строка)
if ((x != (x2 - 1)) && (y != (y2 - 1)))
{
pix32 rightbott = src(x+1, y+1);
//рассчёт матриц для этих двух пикселей
matrix_count(curr, rightbott, matr_r, matr_g, matr_b, matr_c, matr_m, matr_y, matr_L, matr_La, matr_Lb);
}
//условие существования правого пикселя(не последний столбец)
if (x != (x2 - 1))
{
pix32 right = src(x+1,y);
//рассчёт матриц для этих двух пикселей
matrix_count(curr, right, matr_r, matr_g, matr_b, matr_c, matr_m, matr_y, matr_L, matr_La, matr_Lb);
}
}
}
}
//вызываем функцию рассчёта свойств для каждой из цветовых компонент
property_count(matr_r, props.R);
property_count(matr_g, props.G);
property_count(matr_b, props.B);
property_count(matr_c, props.C);
property_count(matr_m, props.M);
property_count(matr_y, props.Y);
property_count(matr_L, props.L);
property_count(matr_La, props.La);
property_count(matr_Lb, props.Lb);
}
//функция рисования матрицы
void matrix_paint(TLayer32& dest, float (&matrix)[256][256], const float prop)
{
//инициирование верхних и нижних границ значений, prop - максимальная вероятность
float top_count = 0, bott_count = 0, top_el = 0, bott_el = prop, curr_top = prop, curr_bott = 0;
for(size_t t = 0; t < 10; ++t)
{
top_el = 0;
for (size_t i = 0; i < 256; ++i)
for(size_t j = 0; j < 256; ++j)
{
if((top_el < matrix[i][j]) && (matrix[i][j] < curr_top))
top_el = matrix[i][j];
}
if(top_el)
curr_top = top_el;
top_count = 0;
for (size_t i = 0; i < 256; ++i)
for(size_t j = 0; j < 256; ++j)
{
if(top_el < matrix[i][j])
++top_count;
}
}
top_el = curr_top;
for(size_t t = 0; t < 10; ++t)
{
bott_el = prop;
for (size_t i = 0; i < 256; ++i)
for(size_t j = 0; j < 256; ++j)
{
if((bott_el > matrix[i][j]) && (matrix[i][j] > curr_bott))
bott_el = matrix[i][j];
}
if(bott_el != prop)
curr_bott = bott_el;
bott_count = 0;
for (size_t i = 0; i < 256; ++i)
for(size_t j = 0; j < 256; ++j)
{
if(bott_el > matrix[i][j])
++bott_count;
}
}
bott_el = curr_bott;
for (size_t i = 0; i < 256; ++i)
for(size_t j = 0; j < 256; ++j)
{
pix32 p;
p.comp[r_rgb] = 0;
p.comp[g_rgb] = 0;
p.comp[b_rgb] = 0;
if(matrix[i][j] < bott_el)
{
float db = 512 / bott_el;
if((matrix[i][j] * db) < 256)
{
p.comp[b_rgb] = matrix[i][j] * db;
p.comp[r_rgb] = 0;
}
else
{
p.comp[r_rgb] = matrix[i][j] * db / 4;
p.comp[b_rgb] = 255 - p.comp[r_rgb];
}
p.comp[g_rgb] = 0;
}
if((matrix[i][j] >= bott_el) && (matrix[i][j] < top_el))
{
float dr = 128 / (top_el - bott_el);
p.comp[g_rgb] = (matrix[i][j] - bott_el) * dr * 2;
p.comp[r_rgb] = 255 - p.comp[r_rgb];
p.comp[b_rgb] = 0;
}
if(matrix[i][j] >= top_el)
{
p.comp[g_rgb] = 255;
p.comp[r_rgb] = 0;
p.comp[b_rgb] = 0;
}
dest(i,j) = p;
}
}
//функция копирования матрицы и свойств
void matr_cpy(const float (&src_matr)[256][256], float (&dest_matr)[256][256], float (&src_prop)[5], float (&dest_prop)[5])
{
for(size_t i = 0; i < 256; ++i)
{
for(size_t j = 0; j < 256; ++j)
dest_matr[i][j] = src_matr[i][j];
if (i < 5)
dest_prop[i] = src_prop[i];
}
}