1 / 26

Programming Assignment 2

Use stacks and queues to extract and count regions in an input image. Assign a distinct gray-level value to each region for visualization purposes. Output a labeled image and the number of regions.

dhebert
Download Presentation

Programming Assignment 2

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Programming Assignment 2 CS 302 Data Structures Dr. George Bebis

  2. Objective: Use Stacks and Queues to Count and Label Regions input image 1. Extract regions and count them 2. Assign a distinct gray-level value to each region (i.e., for visualization purposes) output image Output (1) labeled image (2) number of regions

  3. Project Goals • Improve your skills with manipulating stacksand queues (use array-based stacks/queues). • Illustrate how to convert a recursive algorithm to an iterativeone. • Learn more about image processing.

  4. Application: automatically count and label galaxies in images captured by NASA’s Hubble telescope NASA’s Hubble Telescope Webpage http://hubble.nasa.gov/

  5. Input Image Thresholding Remove Small Holes & Smooth Boundaries Count Regions Display labeled image & report number of regions Labeling and counting regions (1) Add a new option to the driver called “Count/Label Regions” (2) The steps shown in the diagram should be executed when the user selects this option.

  6. Thresholding • Separate most important galaxies from background. • Precursor step to any high-level image analysis system.

  7. threshold(T) – member function • Each pixel in the input image is compared against a threshold. • Values greater than the threshold are set to 255, while values less than the threshold are set to 0.

  8. Results using different thresholds original threshold=128 threshold=10 threshold=230

  9. Input Image Thresholding Remove Small Holes & Smooth Boundaries Count Regions Display labeled image & report number of regions Labeling and counting regions

  10. Remove Small Holes and Smooth Boundaries • Typically, further processing is required to improve the results of thresholding: • Some regions in the thresholded image might contain small holes • Boundaries might be too noisy • We will use dilation/erosion to remove small holes.

  11. dilate() – member function at least one neighbor is 255 otherwise

  12. dilate() - example • Dilation “expands” the size of a region • Adds a layer of boundary pixels original thresholded dilated

  13. erode() – member function at least one neighbor is 0 otherwise

  14. erode() - example • Erosion “shrinks” the regions (i.e., removes a layer of boundary pixels) original thresholded eroded

  15. Removing holes and smoothing boundaries • Threshold, then apply dilation to fill in the holes. • Apply erosion on the dilated image to restore the size of the regions. threshold original dilate results of dilation followed by erosion erode

  16. Input Image Thresholding Remove Small Holes & Smooth Boundaries Count Regions Display labeled image & report number of regions Labeling and counting regions: flowchart

  17. Connected Components Algorithm • Finds the connected components in an image • Assigns a unique label to all the pixels in the same component.

  18. Connected Components 1. Scan the thresholded image to find an unlabeled white (255) pixel and assign it a new label L. 2. Recursively assign the label L to all of its white neighbors. 3. Stop if there are no more unlabeled white pixels. 4. Go to step 1 thresholded image (i.e., after dilation/erosion) output (i.e., labeled) image 1st 2nd

  19. 8-neighbors

  20. int computeComponents(inputImage, outputImage) (client function) initialize outputImage --> 255 (white) connComp=0; for (i=0; i<N; i++) for(j=0; j<M; j++) if(inputImage[i][j] == 255 && outputImage[i][j]==255) { ++connComp; label = connComp * 10; // label findComponent // recursively // or iteratively – user specified findComponentBFS(inputImage, outputImage, i, j, label); findComponentDFS(inputImage, outputImage, i, j, label); } return connComp; Extra credit if you implement the recursive version too.

  21. Breadth-First-Search (BFS) - Queues • The main structure used used by BFS is the queue. • BFS uses a queue to “remember” the neighbors of pixel (i,j) that need to be labeled in future iterations. • The closest neighbors of (i,j) are labeled first. • BFS will first label all pixels at distance 1 from (i,j), then at distance 2, 3, etc.

  22. findComponentBFS(inputImage, outputImage, i, j, label) (client function) Queue.MakeEmpty(); Queue.Enqueue((i,j)); // initialize queue while(!Queue.IsEmpty()) { Queue.Dequeue((pi,pj)); outputImage[pi][pj] = label; // label this pixel for each neighbor (ni,nj) of (pi,pj) // push neighbors if(inputImage[ni][nj] == 255 && outputImage[ni][nj] == 255) { Queue.Enqueue((ni,nj)); outputImage[ni][nj] = -1; // mark this pixel to avoid duplicates } } Extra credit if the queue is templated!

  23. 1 1 P10 255 1 1 1 1 dequeue dequeue p2 p10 p3 p4 p10 p3 p4 P1 dequeue dequeue dequeue continue .. p3 p4 p4 p5 p5

  24. Depth-First-Search (DFS) - Stacks • The main structure used used by DFS is the stack. • DFS uses a stack to “remember” the neighbors of pixel (i,j) that need to be labeled in future iterations. • The most recently visited pixels are visited first (i.e., not the closest neighbors) • DFS follows a path as deep as possible in the image. • When a path ends, DFS backtracks to the most recently visited pixel.

  25. findComponentDFS(inputImage, outputImage, i, j, label) (client function) Stack.MakeEmpty(); Stack.Push((i,j)); // initialize stack while(!Stack.IsEmpty()) { Stack.Pop((pi,pj)); outputImage[pi][pj] = label ; // label this pixel for each neighbor (ni,nj) of (pi,pj) // push neighbors if(inputImage[ni][nj] == 255 && outputImage[ni][nj] == 255) { Stack.Push((ni,nj)); outputImage[ni][nj] = -1; // mark this pixel to avoid duplicates } } Extra credit if the stack is templated!

  26. 1 1 P10 255 1 1 1 1 1 pop pop pop pop pop pop etc. P4 P5 P6 P7 P3 P3 P3 P3 P3 P10 P10 P10 P10 P10 P1 P2 P2 P2 P2 P2

More Related