Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Segmentatsia_izobrazheny_na_osnove_konturnogo_a...doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
4 Мб
Скачать
☆

Список литературы:

1. Я.А. Фурман, А.В. Кревецкий «Введение в контурный анализ. Приложение к обработке изображений и сигналов» 2-у изд., испр. М. 2003г

2. «Сегментация изображения» http://habrahabr.ru/post/128768/ (дата обращения 10.04.2015)

3. «Обнаружение объектов методом Оцу» http://habrahabr.ru/post/112079/ (дата обращения 10.04.2015)

4. Н.М. Новикова «Структурное распознавание образов» Воронеж 2008г.

5. Phiplastic «Модуль бинаризации цветных изображений» http://www.phiplastic.com/prsntns/color_ru.pdf (дата обращения 10.04.2015)

6. Д.П. Николаев, А. А. Сараев «Критерии оценки качества в задаче автоматизированной настройки алгоритмов бинаризации»

7. Ю.А. Огруздина «Алгоритмы сегментации изображений» // Молодежный научно-технический вестник

8. В. Т. Фисенко, Т. Ю. Фисенко «Компьютерная обработка и распознавание изображений» учебное пособие ИТМО СПб 2008

Приложение

  1. Функция ConSquareColorDif (нахождение оптимальной яркости для каждой точки изображения как максимум контуров попадающих в окрестность пиксела)

public static int [][][] ConSquareColorDif (int pixels[], int frameWidth, int frameHeight, int stepsHor, int stepsVer, int brightStep)

//Общее название класса трехмерный массив который возвращает оптимальную яркость для каждого пикселя.

1.1 Объявление переменных

public static int [][][] ConSquareColorDif (int pixels[], int frameWidth, int frameHeight, int stepsHor, int stepsVer, int brightStep)

//Общее название класса трехмерный массив который возвращает оптимальную яркость для каждого пикселя.

{

int iWidth = frameWidth;

int iHeight = frameHeight;

int [][][] result = new int [iHeight][iWidth][2];

int widthStep = iWidth / stepsHor; //Ширина окрестности

int heightStep = iHeight / stepsVer; //Высота окрестности

int [][][]squareBrightMax = new int [iHeight][iWidth][2]; //Оптимальная яркость для каждого пикселя

for (int[][] squareBrightMax1 : squareBrightMax) {

for (int[] squareBrightMax11 : squareBrightMax1) {

Arrays.fill(squareBrightMax11, 0);

}

}

//для каждого порога яркости вычисляем контуры.

for (int brightLevel = 0; brightLevel < 256; brightLevel += brightStep)

{

//получение черно-белой картинки

int[] bwPixs = ImageMethods.blackWhiteScale(pixels, brightLevel, ImageMethods.L_HUMAN_NTSC);

//начало прохода "квадратом"

//определяю отдельно прогонку по пикселям.

int pVer = 0;

int pHor = 0;

for (pVer = 0; pVer < iHeight; pVer++)

{

for (pHor = 0; pHor < iWidth; pHor++)

{

//Суть метода в том что мы берем область вокруг пикселя

//а следовательно мы должны избавиться от случаев, когда мы случайно выходим за границы

1.2 Обработка граничных случаев

int pHorBeg = pHor - widthStep/2;

if (pHorBeg < 0)

{

pHorBeg = 0;

}

int pHorEnd = pHor + widthStep/2;

if (pHorEnd >= iWidth)

{

pHorEnd = iWidth - 1;

}

int pVerBeg = pVer - heightStep/2;

if (pVerBeg < 0)

{

pVerBeg = 0;

}

int pVerEnd = pVer + heightStep/2;

if (pVerEnd >= iHeight)

{

pVerEnd = iHeight - 1;

}

int temp = 0;

//Прогонка в 4 шага, по часовой стрелке

1.3 Поиск оптимального значения яркости

//Верхняя грань слева направо

for (int i = pHorBeg + 1; i <= pHorEnd; i++)

{

int j = pVerBeg;

}

//Правая грань сверху вниз

for (int j = pVerBeg + 1; j <= pVerEnd; j++)

{

int i = pHorEnd;

if (bwPixs[i + j * iWidth] - bwPixs[i + (j - 1) * iWidth] != 0)

{

temp ++;

}

}

//Нижняя грань справа налево

for (int i = pHorEnd - 1; i >= pHorBeg; i--)

{

int j = pVerEnd;

if (bwPixs[i + j * iWidth] - bwPixs[(i + 1) + j * iWidth] != 0)

{

temp ++;

}

}

//Левая грань снизу вверх

for (int j = pVerEnd - 1; j >= pVerBeg; j--)

{

int i = pHorBeg;

if (bwPixs[i + j * iWidth] - bwPixs[i + (j + 1) * iWidth] != 0)

{

temp ++;

}

}

//Сравнение с макс значением

if (squareBrightMax[pVer][pHor][1] < temp)

{

squareBrightMax[pVer][pHor][0] = brightLevel;

squareBrightMax[pVer][pHor][1] = temp;

}

}

}

}

return squareBrightMax;

}

  1. Функция avSquare (сглаживание исходной картинки)

/**

* Возвращает среднюю из оптимальных яркостей пикселей окрестности данного пикселя.

* @param pixContourCount Массив оптимальных значений яркостей для каждого пикселя из окрестнсти.

* @param stepVer Высота прямоугольного окна (окрестности).

* @param stepHor Ширина прямоугольного окна (окрестности).

* @return Трёхмерный массив

* 0, 1 - координаты пикселя в картинке

* 2 - одномерный массив [0] - яркость средняя из оптимальных яркостей [1] - среднее количество контуров по пикселям окрестности

*/

public static int[][][] avSquare(int[][][] pixContourCount, int stepsHor, int stepsVer) {

int height = pixContourCount.length;

int width = pixContourCount[0].length;

int stepHor = width / stepsHor / 2;

int stepVer = height / stepsVer / 2;

int[][][] result = new int[height][width][2];

int tempPtVer = 0;

int tempPtHor = 0;

for (int pVer = 0; pVer < height; pVer++) {

// System.out.println("pVer " + pVer);

for (int pHor = 0; pHor < width; pHor++) {

int tempBright = 0;

int tempQ = 0;

for (int ptVer = pVer - stepVer; ptVer < pVer + stepVer; ptVer++) {

tempPtVer = ptVer;

if (tempPtVer < 0) {

tempPtVer = 0;

}

if (tempPtVer >= height) {

tempPtVer = height - 1;

}

for (int ptHor = pHor - stepHor; ptHor < pHor + stepHor; ptHor++) {

tempPtHor = ptHor;

if (tempPtHor < 0) {

tempPtHor = 0;

}

if (tempPtHor >= width) {

tempPtHor = width - 1;

}

tempBright += pixContourCount[tempPtVer][tempPtHor][0];

tempQ += pixContourCount[tempPtVer][tempPtHor][1];

}

}

result[pVer][pHor][0] = tempBright / (stepHor * stepVer * 4);

result[pVer][pHor][1] = tempQ / (stepHor * stepVer * 4);

}

}

System.out.println("" + result[100][100][0]);

return result;

}

  1. Функция squarBinar (Бинаризует изображение в соответствии с порогом яркости)

public static int[] squarBinar(int pixels[], int[][][] avSquare) {

int height = avSquare.length;

int width = avSquare[0].length;

int[] result = new int[pixels.length];

for (int j = 0, k = 0; j < height; j++) {

for (int i = 0; i < width; i++, k++) {

// result[i][j] = ImageMethods.blackWhiteScale(pixels, avSquare[i][j][0], ImageMethods.L_HUMAN_NTSC);

if (ImageMethods.pixelBrightnessNTSC(pixels[k]) < avSquare[j][i][0]) {

result[k] = 0xFF000000;

} else {

result[k] = 0xFFFFFFFF;

}

}

}

return result;

}

  1. Функция maxNumberContourBrights (нахождение максимального количества контуров при прогонке по яркости для каждого сегмента)

* Картинка разбивается на прямоугольники, для каждого из которых вычисляется

* порог яркости чёрно-белого разбиения, дающий наибольшее число контуров.

* @param pixels Пиксели картинки.

* @param frameWidth Ширина картинки.

* @param frameHeight Высота картинки.

* @param stepsHor Число разбиений по горизонтали.

* @param stepsVer Число разбиений по вертикали.

* @return Массив значений (яркость[0], число[1]) для каждого прямоугольника.

*/

public static int[][][] maxNumberCountourBrights(int pixels[], int frameWidth, int frameHeight, int stepsHor, int stepsVer, int brightStep) {

int[][][] result = new int[stepsVer][stepsHor][2];

int widthStep = frameWidth / stepsHor; //Шаг для ячейки по ширине

int heightStep = frameHeight / stepsVer; //Шаг для ячейки по высоте

int[][] conBrightMax = new int[stepsVer][stepsHor]; //Ф-я порога для каждого сегмента, должна копировать conBrightMax[i][g] из предыдушей функци

int wigthstart = 0; //Эти две переменные нужны чтобы определить квадрат, на котором будет проводиться алгоритм

int heightStart = 0; //выделения контуров

int[] bwPixs;// = new int[pixels.length];

//Для каждого порога яркости вычисляем контуры.

for (int brightLevel = 0; brightLevel < 256; brightLevel += brightStep) {

//Получение чёрно-белой картинки.

bwPixs = ImageMethods.blackWhiteScale(pixels, brightLevel, ImageMethods.L_HUMAN_NTSC); //Black-WHITE

//Получение контуров.

ArrayList<Contour> contours = DetectContourMethods.constructFilledContoursWithProperties(bwPixs, frameWidth, 0xFF000000, 0xFFFFFFFF);

int[][] contourCounts = new int[stepsVer][stepsHor];

//Обнуление счётчика контуров в каждой области.

for (int[] contourCount : contourCounts) {

Arrays.fill(contourCount, 0);

}

for (Contour contour : contours) {

for (int i = 0; i < contourCounts.length; i++) {

for (int j = 0; j < contourCounts[i].length; j++) {

Rectangle rect = new Rectangle(j * widthStep , i * heightStep, widthStep, heightStep);

Point[] points = contour.getContourProperties().points;

int[] px = new int[points.length];

int[] py = new int[points.length];

for (int k = 0; k < points.length; k++) {

px[k] = points[k].x;

py[k] = points[k].y;

}

Polygon pol = new Polygon(px, py, points.length);

if (pol.intersects(j * widthStep , i * heightStep, widthStep, heightStep)) {

contourCounts[i][j]++;

}

}

}

}

for (int i = 0; i < contourCounts.length; i++) {

for (int j = 0; j < contourCounts[i].length; j++) {

if (contourCounts[i][j] > result[i][j][1]){

result[i][j][1] = contourCounts[i][j];

result[i][j][0] = brightLevel;

}

}

}

}

return result;

}

  1. Функция contour contourAnalisys (Сегментация и выявление средних углов направления главной оси инерции)

public static double [][][] contourAnalisys(int squarBinar[], int width, int stepHor, int stepVer){

int height = squarBinar.length / width;

double[][][] result = new double[height][width][1];

ArrayList<Contour> contours = DetectContourMethods.constructFilledContoursWithProperties(squarBinar, width, 0xFF000000, 0xFFFFFFFF);

int widthStep = width / stepHor; //Ширина окрестности

int heightStep = height / stepVer; //Высота окрестности

int pVer = 0;

int pHor = 0;

for(; pVer<width; pVer++){

for(; pHor < height; pHor++){

int pHorBeg = pHor - widthStep / 2;

if (pHorBeg < 0) {

pHorBeg = 0;

}

int pHorEnd = pHor + widthStep / 2;

if (pHorEnd >= width) {

pHorEnd = width - 1;

}

int pVerBeg = pVer - heightStep / 2;

if (pVerBeg < 0) {

pVerBeg = 0;

}

int pVerEnd = pVer + heightStep / 2;

if (pVerEnd >= height) {

pVerEnd = height - 1;

}

int temp = 0;

TreeSet<Integer> cNums = new TreeSet();

for (int iVer = pVerBeg; iVer < pVerEnd; iVer++) {

for (int iHor = pHorBeg; iHor < pHorEnd; iHor++) {

int k = iVer * width + iHor;

int countNum = squarBinar[k] & 0x00FFFFFF;

if (countNum > 0) {

temp++;

cNums.add(countNum);

}

}

}

double sum = 0;

for (int cNum : cNums) {

sum += contours.get(cNum).getContourProperties().angleInertia;

}

result[pVer][pHor][0] = sum / cNums.size();

}

}

return result;

}

2