Marks connected regions with different colors.
| 671 | |
| 672 | // Marks connected regions with different colors. |
| 673 | int vtkImageToPolyDataFilter::ProcessImage(vtkUnsignedCharArray* scalars, int dims[2]) |
| 674 | { |
| 675 | int numPixels = dims[0] * dims[1]; |
| 676 | vtkIdList *wave, *wave2, *tmpWave; |
| 677 | int numIds, regionNumber, i, j, k, id, x, y, numNeighbors; |
| 678 | unsigned char *neighbors[4], *ptr; |
| 679 | unsigned char* pixels = scalars->GetPointer(0); |
| 680 | |
| 681 | // Collect groups of pixels together into similar colored regions. These |
| 682 | // will be eventually grouped into polygons and/or lines. |
| 683 | // |
| 684 | // mark all pixels unvisited |
| 685 | regionNumber = -1; |
| 686 | this->Visited = new int[numPixels]; |
| 687 | memset(this->Visited, -1, numPixels * sizeof(int)); |
| 688 | |
| 689 | // set up the connected traversal |
| 690 | wave = vtkIdList::New(); |
| 691 | wave->Allocate(static_cast<int>(numPixels / 4.0), static_cast<int>(numPixels / 4.0)); |
| 692 | wave2 = vtkIdList::New(); |
| 693 | wave2->Allocate(static_cast<int>(numPixels / 4.0), static_cast<int>(numPixels / 4.0)); |
| 694 | |
| 695 | // visit connected pixels. Pixels are connected if they are topologically |
| 696 | // adjacent and they have "equal" color values. |
| 697 | for (i = 0; i < numPixels; i++) |
| 698 | { |
| 699 | if (this->Visited[i] == -1) |
| 700 | { // start a connected wave |
| 701 | this->Visited[i] = ++regionNumber; |
| 702 | ptr = pixels + 3 * i; |
| 703 | this->PolyColors->InsertValue(3 * regionNumber, ptr[0]); // assign color |
| 704 | this->PolyColors->InsertValue(3 * regionNumber + 1, ptr[1]); |
| 705 | this->PolyColors->InsertValue(3 * regionNumber + 2, ptr[2]); |
| 706 | wave->Reset(); |
| 707 | wave2->Reset(); |
| 708 | |
| 709 | // To prevent creating polygons with inner loops, we're going to start |
| 710 | // the wave as a "vertical" stack of pixels, and then propagate the |
| 711 | // wave horizontally only. |
| 712 | wave->InsertId(0, i); |
| 713 | this->GetIJ(i, x, y, dims); |
| 714 | while ((numNeighbors = this->GetNeighbors(ptr, x, y, dims, neighbors, 1))) |
| 715 | { |
| 716 | id = (neighbors[0] - pixels) / 3; |
| 717 | if (this->Visited[id] == -1 && this->IsSameColor(ptr, neighbors[0])) |
| 718 | { |
| 719 | this->Visited[id] = regionNumber; |
| 720 | wave->InsertNextId(id); |
| 721 | ptr = pixels + 3 * id; |
| 722 | this->GetIJ(id, x, y, dims); |
| 723 | } |
| 724 | else |
| 725 | { |
| 726 | break; |
| 727 | } |
| 728 | } |
| 729 | |
| 730 | // Okay, defined vertical wave, now propagate horizontally |
no test coverage detected