4
\$\begingroup\$

I am trying to design an image processing system on an FPGA to do Canny Edge Detection. The design is shown in the image below.

Canny Edge Detector

I have a large block ram to store my image. then i have smaller line buffers to read only the lines i am processing. I have 3 lines in use at a time ( with 1 other line as a pre-fetch for the next row of processing ).

The challenge I am having is that filter 1 looks at a 9 pixel box and outputs a value for the center pixel. so for a 10x10 image, the filter only outputs data for 8x8 pixels in the middle.

Once filter 1 has finished 3 rows, i want filter 2 to start on the modified pixel values. To pipeline this design, i am having a hard time figuring out how to deal with the 'missing' pixels that filter 1 does not output. what would be the best way to load those for Filter 2? should i have a way to bypass the first+last row and first and last pixel of each other other to my 2nd line buffer? or is there some other way i can do this?

\$\endgroup\$
6
\$\begingroup\$

Why does the first filter not output all of the pixels? It should. You just need to figure out what it needs to produce for the "edge" pixels.

In my video processing designs, I have a separate module that I call a "kernel generator" that sits between the line buffers and the actual filter. It reads the line buffers and outputs the nine input pixels (in parallel) that need to be operated on for any particular output pixel. At the edges of the frame, it produces replicated pixels to replace the ones that would be "off the edge" in the input frame.

What it does at the edges is somewhat application-dependent, but in most cases, it works well to "reflect" the data at the edge of the image. In other words, when you're working on the first row of the image, the missing input data (for the "zeroth" row) is filled in by using data from the second row. The same logic is used at the left, right and bottom edges.

This way, the output of any filter stage has the same number of pixels as its input, and "edge effects" are minimized.

\$\endgroup\$
  • \$\begingroup\$ You can also prepare your system for these unuseful edge lines at the final output. The advantage of adding replicated pixels is that you don't need to consider wrong edge lines. The disadvantage is adding an extra module and some complexity to the system. \$\endgroup\$ – David Quiñones Jun 17 '15 at 14:05
  • \$\begingroup\$ Thank you for your response, Dave! A few concerns with your suggestion. 1. I'll be overwriting rows that are already through the filter. lets say row 3 is already copied. then when the filter is working on row 4 ( it is also using Rows 3 and 5 ), wont that overwrite the values in row 3, which have already gone through the filter? 2. I want to try to avoid copying or altering the processing at the edges. the algorithm is supposed to output the 'edge' pixels as is, so i dont want my implementation to do something else. \$\endgroup\$ – user3397008 Jun 17 '15 at 19:33
  • \$\begingroup\$ I'm not following you. In your diagram, I'm assuming that filter 1 reads from the line buffers on the left and writes to the line buffers on the right, and then filter 2 reads from the line buffers on the right, and so forth. Nothing gets overwritten. If that isn't the case, you need to make your diagram/description more explicit about the details. And there's nothing wrong with setting up the filter so that it passes the edge pixels through unmodified -- you'll still have the condition that each filter puts out as many pixels as it receives, which simplifies the buffer management. \$\endgroup\$ – Dave Tweed Jun 18 '15 at 0:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.