Форум программистов, компьютерный форум CyberForum.ru

Помогите с фильтром Собеля - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 51, средняя оценка - 4.98
andech
Сообщений: n/a
22.09.2009, 20:18     Помогите с фильтром Собеля #1
Мне нужно написать программу, которая бы обрабатывала изображение по фильтру Собеля(выделение границ на изображении). Вроде всё сделал по формулам, но у меня при обработке изображения выдаёт вот это. При применении фильтра Собеля на это же изображение в GIMP'е получается это.
Если кто-нибудь занимается изображениями помогите пожалуйста. Эту же прогу делал со scanline вместо попиксельного обращения, результат такой же.
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
#include <vcl.h>
#include <math.h>
#pragma hdrstop
#include <tchar.h>
#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
   int GX[3][3], GY[3][3], sumX = 0, sumY = 0, SUM = 0;
    Graphics::TBitmap *img = new Graphics::TBitmap;
    img->LoadFromFile("1.bmp");
 
   GX[3][3] = -1; GX[3][3] = 0; GX[3][3] = 1;
   GX[3][3] = -2; GX[3][3] = 0; GX[3][3] = 2;
   GX[3][3] = -1; GX[3][3] = 0; GX[3][3] = 1;
 
   GY[3][3] =  1; GY[3][3] = 2; GY[3][3] = 1;
   GY[3][3] =  0; GY[3][3] = 0; GY[3][3] = 0;
   GY[3][3] = -1; GY[3][3] = -2; GY[3][3] = -1;
 
    for (int Y = 0; Y < img->Height; Y++) {
        for (int X = 0; X < img->Width; X++) {
            sumX = 0;
            sumY = 0;
            if (Y == 0 || Y == img->Height)
                SUM = 0;
            else if (X == 0 || X == img->Width)
                SUM = 0;
            else {
                for (int I = -1; I <= 1; I++) {
                    for (int J = -1; J <= 1; J++) {
 
                        int piX = J + X;
                        int piY = I + Y;
 
                        COLORREF pixVal = img->Canvas->Pixels[piX][piY];
 
                        int R = GetRValue(pixVal);
                        int G = GetGValue(pixVal);
                        int B = GetBValue(pixVal);
 
                        int NC = (R + G + B) / 3;
 
                        sumX = sumX + (NC) * GX[J + 1][I + 1];
                        sumY = sumY + (NC) * GY[J + 1][I + 1];
                    }
                }
                SUM = sqrt(pow(sumX,2) + pow(sumY,2));
            }
            if (SUM > 255)
                SUM = 255;
            if (SUM < 0)
                SUM = 0;
            int newPixel = SUM;
            COLORREF newPixCol = RGB(newPixel, newPixel, newPixel);
            img->Canvas->Pixels[X][Y] = newPixCol;
        }
    }
    img->SaveToFile("2.bmp");
    return 0;
}
Миниатюры
Помогите с фильтром Собеля   Помогите с фильтром Собеля   Помогите с фильтром Собеля  

Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.09.2009, 20:18     Помогите с фильтром Собеля
Посмотрите здесь:

Оператор Собеля для каждого елемента матрицы C++
Посчитать раздел границы фильтром Собеля и псевдомедианой C++
C++ С++ и OpenCV. Оператор Собеля
C++ Нахождение границ изображения оператором Собеля

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Adler
 Аватар для Adler
78 / 78 / 3
Регистрация: 07.05.2009
Сообщений: 316
23.09.2009, 00:43     Помогите с фильтром Собеля #2
C++
1
2
3
4
5
6
7
8
   
   GX[3][3] = -1; GX[3][3] = 0; GX[3][3] = 1;
   GX[3][3] = -2; GX[3][3] = 0; GX[3][3] = 2;
   GX[3][3] = -1; GX[3][3] = 0; GX[3][3] = 1;
 
   GY[3][3] =  1; GY[3][3] = 2; GY[3][3] = 1;
   GY[3][3] =  0; GY[3][3] = 0; GY[3][3] = 0;
   GY[3][3] = -1; GY[3][3] = -2; GY[3][3] = -1;
я плохо представляю что это, но думаю должно быть так:
C++
1
2
3
4
5
6
7
   GX[0][0] = -1; GX[0][1] = 0; GX[0][2] = 1;
   GX[1][0] = -2; GX[1][1] = 0; GX[1][2] = 2;
   GX[2][0] = -1; GX[2][1] = 0; GX[2][2] = 1;
 
   GY[0][0] =  1; GY[0][1] = 2; GY[0][2] = 1;
   GY[1][0] =  0; GY[1][1] = 0; GY[1][2] = 0;
   GY[2][0] = -1; GY[2][1] = -2; GY[2][2] = -1;
Добавлено через 4 минуты
да, так оно и есть.
*почитал маны*
andech
Сообщений: n/a
25.09.2009, 15:00     Помогите с фильтром Собеля #3
Спасибо за помощь! Действительно что-то я реально с массивами ступил жестоко.
Теперь прога нормально работает даже с scanline. Выкладываю код, вдруг кому понадобится.
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
#include <vcl.h>
#include <math.h>
#pragma hdrstop
#include <tchar.h>
#pragma argsused
Graphics::TBitmap *Sobel(Graphics::TBitmap *image);
int _tmain(int argc, _TCHAR* argv[])
{
    Graphics::TBitmap *img = new Graphics::TBitmap;
    img->LoadFromFile("1.bmp");
    Sobel(img)->SaveToFile("2.bmp");
    return 0;
}
 
Graphics::TBitmap *Sobel(Graphics::TBitmap *img) {
    Graphics::TBitmap *returnImage = new Graphics::TBitmap;
    returnImage->SetSize(img->Width, img->Height);
    returnImage->PixelFormat = pf24bit;
    Byte *ptr, *ptrup, *ptrdown, *ptrres, *ptrcur;
    int sumX = 0, sumY = 0;
    short SUM = 0;
 
    int GX[3][3]={{-1, 0, 1},
                 {-2, 0, 2},
                 {-1, 0, 1}};
 
    int GY[3][3]={{ 1, 2, 1},
                 { 0, 0, 0},
                 {-1,-2,-1}};
 
    for (int Y = 1; Y < img->Height - 1; Y++) {
        ptrres = (Byte*)returnImage->ScanLine[Y];
        ptr = (Byte*)img->ScanLine[Y];
        ptrup = (Byte*)img->ScanLine[Y - 1];
        ptrdown = (Byte*)img->ScanLine[Y + 1];
        for (int X = 0; X < 3 * img->Width; X += 3) {
            if (Y - 1 == 0 || Y + 1 == img->Height - 1) SUM = 0;
            else if (X == 0 || X == img->Width - 3) SUM = 0;
            else {
                sumX = 0;
                sumY = 0;
                for (int I = -1; I <= 1; I++) {
                    for (int J = -1; J <= 1; J++) {
                        switch(I) {
                        case -1:ptrcur = ptrup; break;
                        case 0:ptrcur = ptr; break;
                        case 1:ptrcur = ptrdown; break;
                        }
                        int piX = 3 * J + X;
                        int NC = 0.299 * ptrcur[piX + 2] + 0.587 * ptrcur
                            [piX + 1] + 0.114 * ptrcur[piX];
                        sumX = sumX + NC * GX[I + 1][J + 1];
                        sumY = sumY + NC * GY[I + 1][J + 1];
                    }
                }
                SUM = abs(sumX) + abs(sumY);
                if (SUM > 255) SUM = 255;
                if (SUM < 0) SUM = 0;
            }
            SUM = 255 - abs(SUM);
            ptrres[X + 2] = SUM;
            ptrres[X + 1] = SUM;
            ptrres[X] = SUM;
        }
    }
    return returnImage;
}
Gendalf147
3 / 5 / 0
Регистрация: 09.12.2012
Сообщений: 97
11.04.2013, 19:21     Помогите с фильтром Собеля #4
Я в билдере запустил - программа не создает того, что надо. Только закрашивает в черный цвет 90% картинки.
Evgen192
 Аватар для Evgen192
1 / 1 / 0
Регистрация: 10.08.2013
Сообщений: 27
09.02.2014, 22:15     Помогите с фильтром Собеля #5
А может у кого то есть этот же фильтр Собеля но ток для C#? Очень нужно
Yandex
Объявления
09.02.2014, 22:15     Помогите с фильтром Собеля
Ответ Создать тему
Опции темы

Текущее время: 00:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru