Размытие изображения в C ++.Проблема с копией матрицы - PullRequest
0 голосов
/ 21 июля 2010

Я ввожу матрицу значений черно-белых пикселей, а затем размываю внутреннюю часть, используя метод усреднения. У меня есть программа, проходящая должным образом, но мне нужна постоянная копия исходной матрицы для циклов for, чтобы использовать при пошаговом выполнении. Как я могу это сделать?

#include<iostream>
using namespace std;

/****blurImage*****************************************************************************************************
 * main -- Program to blur a grayscale image given the pixel values and their location
 * 
 * Arguments: none
 * 
 * returns: 0
 *****************************************************************************************************************/

void blurImage(int matrix[100][100], int matRow, int matCol, int image[100][100]);

int main(){

    int matRow;
    int matCol;
    bool checkDataOk;
    int matrix[100][100];
    int image[100][100];

    cout << "Enter Image Width (in pixels):";
    cin >> matCol;

    cout << "Enter Image Height (in pixels):";
    cin >> matRow;

    if (matRow <=0 || matCol <=0 )
        checkDataOk = false;
    else checkDataOk = true;


    if(checkDataOk){

        cout << "Enter Pixel Values (left-->right):" << endl;
        int tmp;
        for (int i = 0; i < matRow; i++)
        {
            for (int j = 0 ; j < matCol; j++)
            {
                cin >> tmp;
                matrix[i][j] = tmp;
            }
        }

        blurImage(matrix, matRow, matCol, image);

        cout << endl;
        cout << "Output:" << endl;
        for(int i=0; i<matRow; i++){
            for(int j=0; j<matCol; j++){
                cout << matrix[i][j] << endl;
            }
        }
    }
    else cout << "Invalid Row/Column size";

    return 0;
}

void blurImage(int matrix[100][100], int matRow, int matCol, int image[100][100]){

    for(int i=1; i<(matRow-1); i++){        // start index at 1 and stop at -1 so we don't access outside the image
        for(int j=1; j<(matCol-1); j++){
            int total = 0;

            for(int n=(i-1); n<(i+2); n++){ // start at the top left corner of our current index and loop the 3x3 sub-matrix adding to the total
                for(int m=(j-1); m<(j+2); m++){
                    image = matrix;
                    total += image[n][m];
                }
            }

            int avg = total/9;              // get the average, and set the current index to the average
            matrix[i][j] = avg;
        }
    }

}

Если я введу эту матрицу 6x5:

0   0   255 0   0
0   255 0   255 0
255 255 0   255 255
255 255 255 255 255
255 0   0   0   255
255 0   0   0   255
0   0   255 0   0

Я должен получить:

0   0   255 0   0
0   113 141 113 0 
255 170 198 170 255 
255 170 141 170 255 
255 141 85  141 255 
255 0   0   0   255 
0   0   255 0   0

Ответы [ 3 ]

2 голосов
/ 21 июля 2010

Эта строка:

image = matrix;

фактически не копирует массив.Если я не ошибаюсь, это присвоение указателя (то есть image будет указывать на matrix сейчас), а не копия данных.

Что (я думаю) вы хотите:

memcpy(image, matrix, sizeof(image));

Поскольку изображение и матрица являются массивами одного типа, мы можем сделать копию памяти для передачи содержимого.Вы также можете использовать циклы для выполнения копирования, но это проще и быстрее.

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

Примечание: вам понадобится #include <string.h>, чтобы использовать memcpy.

0 голосов
/ 21 июля 2010

Это только косвенно связано с вашим вопросом, но в любом случае вы обязательно столкнетесь с проблемой, так что я дам вам предупреждение.То, как вы выполняете фильтрацию, занимает около matCol * matRow * k * k операций, где k - ширина вашего ядра размытия.Хотя это нормально, когда k=3, оно быстро станет слишком медленным.

Простой способ сделать это быстрее - сначала размывать изображение только по горизонтали, а затем размывать промежуточный результат по вертикали.Это займет порядка 2 * matCol * matRow * k операций и даст тот же результат (чтобы избежать округления, не делите на k в середине процесса - оставьте промежуточный пиксель суммы )

Если вам нужна интересная головоломка, есть отличный способ сделать это, который занимает примерно одно и то же время, независимо от от заданного k.

0 голосов
/ 21 июля 2010

"но мне нужна постоянная копия исходная матрица для циклов для использовать при переходе через "

Да! Так что не изменяйте свой ввод («матрица») в функции размытия. Изменяйте только выходные данные («изображение»).

Когда функция blurImage () возвращается, «матрица» не изменяется, а «изображение» будет содержать результат.

Таким образом, когда вы печатаете вывод, используйте «изображение» вместо «матрица». Если вы действительно хотите скопировать «изображение» в «матрицу», сделайте так, как предлагает Джои Адамс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...