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

Матрица свёртки - C++

Восстановить пароль Регистрация
 
танкист34
-62 / 0 / 0
Регистрация: 15.03.2013
Сообщений: 328
15.05.2014, 20:49     Матрица свёртки #1
Добрый день! Нашёл код применения фильтра на изображени, написанный на С#.
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
68
69
70
71
public static class Convolution
  {
    public static Bitmap Apply(Bitmap input, double[,] kernel)
    {
      //Получаем байты изображения
      byte[] inputBytes = BitmapBytes.GetBytes(input);
      byte[] outputBytes = new byte[inputBytes.Length];
 
      int width = input.Width;
      int height = input.Height;
 
      int kernelWidth = kernel.GetLength(0);
      int kernelHeight = kernel.GetLength(1);
 
      //Производим вычисления
      for (int x = 0; x < width; x++)
      {
        for (int y = 0; y < height; y++)
        {
          double rSum = 0, gSum = 0, bSum = 0, kSum = 0;
 
          for (int i = 0; i < kernelWidth; i++)
          {
            for (int j = 0; j < kernelHeight; j++)
            {
              int pixelPosX = x + (i - (kernelWidth / 2));
              int pixelPosY = y + (j - (kernelHeight / 2));
              if ((pixelPosX < 0) ||
                (pixelPosX >= width) ||
                (pixelPosY < 0) ||
                (pixelPosY >= height)) continue;
 
              byte r = inputBytes[3 * (width * pixelPosY + pixelPosX) + 0];
              byte g = inputBytes[3 * (width * pixelPosY + pixelPosX) + 1];
              byte b = inputBytes[3 * (width * pixelPosY + pixelPosX) + 2];
 
              double kernelVal = kernel[i, j];
 
              rSum += r * kernelVal;
              gSum += g * kernelVal;
              bSum += b * kernelVal;
 
              kSum += kernelVal;
            }
          }
 
          if (kSum <= 0) kSum = 1;
 
          //Контролируем переполнения переменных
          rSum /= kSum;
          if (rSum < 0) rSum = 0;
          if (rSum > 255) rSum = 255;
 
          gSum /= kSum;
          if (gSum < 0) gSum = 0;
          if (gSum > 255) gSum = 255;
 
          bSum /= kSum;
          if (bSum < 0) bSum = 0;
          if (bSum > 255) bSum = 255;
 
          //Записываем значения в результирующее изображение
          outputBytes[3 * (width * y + x) + 0] = (byte)rSum;
          outputBytes[3 * (width * y + x) + 1] = (byte)gSum;
          outputBytes[3 * (width * y + x) + 2] = (byte)bSum;
        }
      }
      //Возвращаем отфильтрованное изображение
      return BitmapBytes.GetBitmap(outputBytes, width, height);
    }
  }
попробывал переделать на С++ в среде Qt
C++ (Qt)
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
68
69
70
71
72
void MainWindow::pixels_filter() //получение вектора значений пикселей изображени, используя scanLine(int);
{
    int kernelWidth = 3, kernelHeight = 3; // размер матрицы свёртки
    double kernel[3][3];
 
    kernel[0][0] = -1;
    kernel[0][1] = -1;
    kernel[0][2] = -1;
 
    kernel[0][0] = -1;
    kernel[1][0] = 9;
    kernel[2][0] = -1;
 
    kernel[0][0] = -1;
    kernel[1][0] = -1;
    kernel[2][0] = -1;
 
    ui->dop_browser->setText(QString::number(massiv_zn.size())); //1764000 пикселей в данном изображении
    massiv_zn_itog.resize(px.width()*px.height());
 
    for(int x = 0, ttt = 0; x < px.width(); x++, ttt = ttt + px.width())
    {
        for(int y = 0; y < px.height(); y++)
        {
 
            double rSum = 0, gSum = 0, bSum = 0, kSum = 0;
 
            for (int i = 0; i < kernelWidth; i++)
            {
              for (int j = 0; j < kernelHeight; j++)
              {
                int pixelPosX = x + (i - (kernelWidth / 2));
                int pixelPosY = y + (j - (kernelHeight / 2));
                if ((pixelPosX < 0) || (pixelPosX >= px.width()) || (pixelPosY < 0) ||
                  (pixelPosY >= px.height())) continue;
 
                int r = qRed(massiv_zn[3 * (px.width() * pixelPosY + pixelPosX) + 0]); //вектор одномерный massiv_zn содержит значение пикселов
                int g = qGreen(massiv_zn[3 * (px.width() * pixelPosY + pixelPosX) + 1]);
                int b = qBlue(massiv_zn[3 * (px.width() * pixelPosY + pixelPosX) + 2]);
 
                double kernelVal = *kernel[i, j];
 
                rSum += r * kernelVal;
                gSum += g * kernelVal;
                bSum += b * kernelVal;
 
                kSum += kernelVal;
              }
 
            }
 
            if (kSum <= 0) kSum = 1;
 
            //Контролируем переполнения переменных
            rSum /= kSum;
            if (rSum < 0) rSum = 0;
            if (rSum > 255) rSum = 255;
 
            gSum /= kSum;
            if (gSum < 0) gSum = 0;
            if (gSum > 255) gSum = 255;
 
            bSum /= kSum;
            if (bSum < 0) bSum = 0;
            if (bSum > 255) bSum = 255;
 
 
           massiv_zn_itog[ttt + y] = qRgb(rSum,gSum,bSum); /*massiv_zn_itog одномерный вектор значения пикселов после применения фильтра*/
 
        }
    }
}
Проблема заключается в том, что выскакивает ошибка "out of range vector<T>" при работе данной функции. Почему на С# работает, а на С++ нет? что сделал не так? спасибо
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.05.2014, 20:49     Матрица свёртки
Посмотрите здесь:

Матрица C++
матрица C++
C++ Матрица
C++ Матрица
C++ Матрица
C++ Матрица
C++ матрица
Матрица С++ C++

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать тему
Опции темы

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