ALGORITMO ZHANG-SUEN

NAUTILUZ 22/07/2014 15:08:52
#439739
Ola caros amigos, estou precisando de uma ajuda, tenho este código abaixo para esqueletizar imagens
mas não tenho em VB6, alguém teria uma função já pronta para suprimir pixels binarios de uma matriz em VB6
ou então teria que converter todo este código que não tenho idéia!, para VB6
Metodologia:

While points are deleted do
For all pixels p(i,j) do
if (a) 2 ≤ B(P1) ≤ 6
(b) A(P1) = 1
(c) Apply one of the following:
1. P2 x P4 x P6 = 0 in odd iterations
2. P2 x P4 x P8 = 0 in even iterations
(d) Apply one of the following:
1. P4 x P6 x P8 = 0 in odd iterations
2. P2 x P6 x P8 = 0 in even iterations
then
Delete pixel p(i,j)
end if
end for
end while

Codigo em C#:

/**
* Code for thinning a binary image using Zhang-Suen algorithm.
*/
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

/**
* Perform one thinning iteration.
* Normally you wouldn[ô]t call this function directly from your code.
*
* @param im Binary image with range = 0-1
* @param iter 0=even, 1=odd
*/
void thinningIteration(cv::Mat& im, int iter)
{
cv::Mat marker = cv::Mat::zeros(im.size(), CV_8UC1);

for (int i = 1; i < im.rows-1; i++)
{
for (int j = 1; j < im.cols-1; j++)
{
uchar p2 = im.at<uchar>(i-1, j);
uchar p3 = im.at<uchar>(i-1, j+1);
uchar p4 = im.at<uchar>(i, j+1);
uchar p5 = im.at<uchar>(i+1, j+1);
uchar p6 = im.at<uchar>(i+1, j);
uchar p7 = im.at<uchar>(i+1, j-1);
uchar p8 = im.at<uchar>(i, j-1);
uchar p9 = im.at<uchar>(i-1, j-1);

int A = (p2 == 0 && p3 == 1) + (p3 == 0 && p4 == 1) +
(p4 == 0 && p5 == 1) + (p5 == 0 && p6 == 1) +
(p6 == 0 && p7 == 1) + (p7 == 0 && p8 == 1) +
(p8 == 0 && p9 == 1) + (p9 == 0 && p2 == 1);
int B = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
int m1 = iter == 0 ? (p2 * p4 * p6) : (p2 * p4 * p8);
int m2 = iter == 0 ? (p4 * p6 * p8) : (p2 * p6 * p8);

if (A == 1 && (B >= 2 && B <= 6) && m1 == 0 && m2 == 0)
marker.at<uchar>(i,j) = 1;
}
}

im &= ~marker;
}

/**
* Function for thinning the given binary image
*
* @param im Binary image with range = 0-255
*/
void thinning(cv::Mat& im)
{
im /= 255;

cv::Mat prev = cv::Mat::zeros(im.size(), CV_8UC1);
cv::Mat diff;

do {
thinningIteration(im, 0);
thinningIteration(im, 1);
cv::absdiff(im, prev, diff);
im.copyTo(prev);
}
while (cv::countNonZero(diff) > 0);

im *= 255;
}

/**
* This is an example on how to call the thinning function above.
*/
int main()
{
cv::Mat src = cv::imread([Ô]test_image.png[Ô]);
if (src.empty())
return -1;

cv::Mat bw;
cv::cvtColor(src, bw, CV_BGR2GRAY);
cv::threshold(bw, bw, 10, 255, CV_THRESH_BINARY);

thinning(bw);

cv::imshow([Ô]src[Ô], src);
cv::imshow([Ô]dst[Ô], bw);
cv::waitKey(0);

return 0;
}

Tipo de saida:

RO.DRIGOSG 23/07/2014 14:49:18
#439777
NAUTILUZ,

Se você tem o código C#, pode utilizar um conversor de código para transformar seu código C# e VB.
Segue site:

http://converter.telerik.com/

Veja se isso te ajuda.
NAUTILUZ 23/07/2014 15:02:20
#439778
Ola RO_DRIGOSG,
O site que você indicou retorna erro, afinal o código não é simples, e também tem bibliotecas que talvez não seja compatível com VB..
Agradeço pela dica..
NAUTILUZ 25/07/2014 17:29:08
#439871
Bom, depois de muito estudo fiz a minha propia função, esta ai a arte.

Function ZHANG_SUEN()
[ô]ALGORITMO esqueletização ZHANG-SUEN
[ô]Matriz global POn = 0/1

Dim cont As Integer
Dim delList() As Integer
Dim neighbor, connectivity As Integer
Dim p, p1, p2, p3, p4, p5, p6, p7, p8 As Integer

neighbor = 0
connectivity = 0
cont = 0
For i = 4 To 280 - 4
For j = 4 To 130 - 4
If POn(i, j) = 1 Then
p1 = POn(i - 1, j)
p2 = POn(i - 1, j + 1)
p3 = POn(i, j + 1)
p4 = POn(i + 1, j + 1)
p5 = POn(i + 1, j)
p6 = POn(i + 1, j - 1)
p7 = POn(i, j - 1)
p8 = POn(i - 1, j - 1)

neighbor = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8

If p1 = 0 And p2 = 1 Then connectivity = connectivity + 1
If p2 = 0 And p3 = 1 Then connectivity = connectivity + 1
If p3 = 0 And p4 = 1 Then connectivity = connectivity + 1
If p4 = 0 And p5 = 1 Then connectivity = connectivity + 1
If p5 = 0 And p6 = 1 Then connectivity = connectivity + 1
If p6 = 0 And p7 = 1 Then connectivity = connectivity + 1
If p7 = 0 And p8 = 1 Then connectivity = connectivity + 1
If p8 = 0 And p1 = 1 Then connectivity = connectivity + 1

End If

If connectivity = 1 And (neighbor >= 2 And neighbor <= 6) And _
(p1 * p3 * p5 = 0) And (p3 * p5 * p7 = 0) Then
cont = cont + 1
ReDim Preserve delList(cont)
delList(cont) = i

cont = cont + 1
ReDim Preserve delList(cont)
delList(cont) = j
End If

connectivity = 0
neighbor = 0
Next j, i

For i = 1 To cont Step 2
POn(delList(i), delList(i + 1)) = 0 [ô]zera
Next i

neighbor = 0
connectivity = 0
If cont = 0 Then Exit Function

For i = 4 To 280 - 4
For j = 4 To 130 - 4

If POn(i, j) = 1 Then
p1 = POn(i - 1, j)
p2 = POn(i - 1, j + 1)
p3 = POn(i, j + 1)
p4 = POn(i + 1, j + 1)
p5 = POn(i + 1, j)
p6 = POn(i + 1, j - 1)
p7 = POn(i, j - 1)
p8 = POn(i - 1, j - 1)

neighbor = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8

If p1 = 0 And p2 = 1 Then connectivity = connectivity + 1
If p2 = 0 And p3 = 1 Then connectivity = connectivity + 1
If p3 = 0 And p4 = 1 Then connectivity = connectivity + 1
If p4 = 0 And p5 = 1 Then connectivity = connectivity + 1
If p5 = 0 And p6 = 1 Then connectivity = connectivity + 1
If p6 = 0 And p7 = 1 Then connectivity = connectivity + 1
If p7 = 0 And p8 = 1 Then connectivity = connectivity + 1
If p8 = 0 And p1 = 1 Then connectivity = connectivity + 1
End If

If connectivity = 1 And (neighbor >= 2 And neighbor <= 6) And _
(p1 * p3 * p7 = 0) And (p1 * p5 * p7 = 0) Then
cont = cont + 1
ReDim Preserve delList(cont)
delList(cont) = i

cont = cont + 1
ReDim Preserve delList(cont)
delList(cont) = j
POn(i, j) = 0
End If
connectivity = 0
neighbor = 0
Next j, i

For i = 1 To cont Step 2
POn(delList(i), delList(i + 1)) = 0 [ô]zera
Next i
End Function
Tópico encerrado , respostas não são mais permitidas