Algoritmo de desbaste Zhang-Suen C #

Estou tentando escrever um algoritmo de desbaste de Zhang-Suen em C # seguindo esta diretriz, sem processar as margens.

Na função 'zhangsuen', estou lendo a imagem 'imgUndo' e gravando na imagem 'img'. Os ponteiros dataPtrOrigin_aux dentro dos ciclos for são usados para ler os 9 pixels dentro de uma janela 3x3, de modo que dataPtrOrigin_aux5 seja o pixel central dessa janela e essa janela se moverá ao longo de toda a imagem, movendo-se da esquerda para a direita e de cima para baixo. Em cada pixel, se as declarações forem verificadas verdadeiras, as alterações correspondentes serão feitas na imagem a ser gravada pelo ponteiro dataPtrFinal.

Observe que eu armazenei os vizinhos do pixel atual dentro de uma matriz de 8 elementos. Como tal, eles serão armazenados seguindo esta ordem:

        internal static void zhangsuen(Image<Bgr, byte> img, Image<Bgr, byte> imgUndo)
    {
        unsafe
        {

            MIplImage m = img.MIplImage; //Image to be written.
            MIplImage mUndo = imgUndo.MIplImage; //Image to be read.
            byte* dataPtrFinal = (byte*)m.imageData.ToPointer();
            byte* dataPtrUndo = (byte*)mUndo.imageData.ToPointer();

            int width = img.Width; //Width of the image.
            int height = img.Height; //Height of the image.
            int nChan = m.nChannels; //3 channels (R, G, B).
            int wStep = m.widthStep; //Total width of the image (including padding).
            int padding = wStep - nChan * width; //Padding at the end of each line.

            int x, y, i;

            int[] neighbours = new int[8]; //Store the value of the surrounding neighbours in this array.

            int step; //Step 1 or 2.
            int[] sequence = { 1, 2, 4, 7, 6, 5, 3, 0, 1 };
            int blackn = 0; //Number of black neighbours.
            int numtransitions = 0; //Number of transitions from white to black in the sequence specified by the array sequence.
            int changed = 1; //Just so it enters the while.

            bool isblack = false;

            int counter = 0;


            while(changed > 0)
            {
                changed = 0;

                if (counter % 2 == 0) //We want to read all the pixels in the image before going to the next step
                    step = 1;
                else
                    step = 2;

                for (y = 0; y < height; y++)
                {
                    for (x = 0; x < width; x++)
                    {

                            byte* dataPtrOrigin_aux1 = (byte*)(dataPtrUndo + (y - 1) * m.widthStep + (x - 1) * m.nChannels);
                            byte* dataPtrOrigin_aux2 = (byte*)(dataPtrUndo + (y - 1) * m.widthStep + (x) * m.nChannels);
                            byte* dataPtrOrigin_aux3 = (byte*)(dataPtrUndo + (y - 1) * m.widthStep + (x + 1) * m.nChannels);
                            byte* dataPtrOrigin_aux4 = (byte*)(dataPtrUndo + (y) * m.widthStep + (x - 1) * m.nChannels);
                            byte* dataPtrOrigin_aux5 = (byte*)(dataPtrUndo + (y) * m.widthStep + (x) * m.nChannels);
                            byte* dataPtrOrigin_aux6 = (byte*)(dataPtrUndo + (y) * m.widthStep + (x + 1) * m.nChannels);
                            byte* dataPtrOrigin_aux7 = (byte*)(dataPtrUndo + (y + 1) * m.widthStep + (x - 1) * m.nChannels);
                            byte* dataPtrOrigin_aux8 = (byte*)(dataPtrUndo + (y + 1) * m.widthStep + (x) * m.nChannels);
                            byte* dataPtrOrigin_aux9 = (byte*)(dataPtrUndo + (y + 1) * m.widthStep + (x + 1) * m.nChannels);


                        if (x > 0 && y > 0 && x < width - 1 && y < height - 1)
                        {
                            if (dataPtrOrigin_aux5[0] == 0)
                                isblack = true;

                            if (isblack)
                            {

                                neighbours[0] = dataPtrOrigin_aux1[0];
                                neighbours[1] = dataPtrOrigin_aux2[0];
                                neighbours[2] = dataPtrOrigin_aux3[0];
                                neighbours[3] = dataPtrOrigin_aux4[0];
                                neighbours[4] = dataPtrOrigin_aux6[0];
                                n,eighbours[5] = dataPtrOrigin_aux7[0];
                                neighbours[6] = dataPtrOrigin_aux8[0];
                                neighbours[7] = dataPtrOrigin_aux9[0];

                                for(i = 0; i <= 7; i++)
                                {
                                    if (neighbours[i] == 0)
                                        blackn++;

                                    if (neighbours[sequence[i]] - neighbours[sequence[i + 1]] == 255) //número de transições de branco para preto, seguindo a ordem do vector sequence
                                        numtransitions++;
                                }


                                if ((blackn >= 2 && blackn <= 6) && numtransitions == 1)
                                {
                                        if (step == 1 && (neighbours[1] == 255 || neighbours[4] == 255 || neighbours[6] == 255) && (neighbours[4] == 255 || neighbours[6] == 255 || neighbours[3] == 255))
                                        {
                                            dataPtrFinal[0] = 255;
                                            dataPtrFinal[1] = 255;
                                            dataPtrFinal[2] = 255;

                                            changed++;
                                        }

                                        if (step == 2 && (neighbours[1] == 255 || neighbours[4] == 255 || neighbours[3] == 255) && (neighbours[1] == 255 || neighbours[6] == 255 || neighbours[3] == 255))
                                        {
                                            dataPtrFinal[0] = 255;
                                            dataPtrFinal[1] = 255;
                                            dataPtrFinal[2] = 255;

                                            changed++;
                                        }

                                }
                            }
                        }


                        dataPtrFinal += nChan;

                        isblack = false;
                        blackn = 0;
                        numtransitions = 0;

                    }
                    dataPtrFinal += padding;

                }


                dataPtrUndo = (byte*)m.imageData.ToPointer(); //Change the image to be read to the one that has just been written.

                counter++;

            }


        }
    }

Ao terminar de ler a primeira imagem e escrever as alterações na imagem 'img' (Assim que o ciclo para (y = 0; y <altura; y ++) terminar, quero que a imagem que acabei de escrever seja a que desejo leia no próximo ciclo para que mais diluição seja feita.Tentei fazer isso com a linha

dataPtrUndo = (byte*)m.imageData.ToPointer();

Embora em algum valor do contador seja maior que 0 (depende da imagem lida), recebo um erro informando que foi tentada a gravação de memória protegida, o que indica que tentei gravar fora dos limites da imagem, mas não entendo o porquê. É a última atribuição ao dataPtrUndo que estou fazendo erroneamente?

questionAnswers(2)

yourAnswerToTheQuestion