4

I am having issue with opencv's Sobel edge detector. From its documentation it seems to work only for horizontal and vertical direction edges (by specifying 0,1 or 1,0). Has anyone got idea how to get the diagonal edges 45deg and 135deg with cvSobel (not Canny methods). Matlab has a soultion with its edge(I,'sobel' ...) option, but my code is all in c++ and I would like to keep it as such.

Thanks for suggestions and solutions.

luhfluh
  • 487
  • 2
  • 8
  • 26
  • @luhfluh, I have (1, 1) working. I'm using OpenCV2.2. Where in the documentation, this restriction is mentioned? – Andrey Sboev May 26 '11 at 12:28
  • @Andrey: (1,1) is not diagonal - it's a double derivative (in x and in y). – etarion May 26 '11 at 12:52
  • @etarion, I know that. With (1,1) one can retrieve all edges including diagonal. Now I understand that OP wants diagonal only edges :) – Andrey Sboev May 26 '11 at 13:06
  • 1
    @luhfluh, try to rotate kernels which are used in sobel and invoke custom filter – Andrey Sboev May 26 '11 at 13:09
  • Thanks @Andrey and @Etarion for your suggestions. I however found a way with the following sudo code from http://opencv-users.1802565.n2.nabble.com/Edge-orientation-td3146691.html: Pseudo Code: cvSobel(grayimg, dx, 1, 0, 3) cvSobel(grayimg, dy, 1, 0, 3) for j in height for i in width mag = sqrt(dx[i,j]^2 + dy[i,j]^2) if mag > thresh orient[i,j] = atan2(dy[i,j], dx[i,j]) else orient[i,j] = 4 – luhfluh May 26 '11 at 13:25
  • That does not do what your original question asked for. – etarion May 26 '11 at 14:18
  • @etarion, keeping in mind that Opencv (2.1 at least) does not have a direct method/function to do what I was looking for, and having to understand that the diagonal edges from a mathematical point (hypotenuse) can be found from known vertical and horizontal edges, that IS what I used as referenced above. Any omissions and/or wrong assumptions made, you can point out BUT to say it does not fulfill my question...I ASKED the question...;) – luhfluh Jun 07 '12 at 06:45
  • @luhfluh, It might be the answer to what you thought when you asked the question, but it is not the answer to what you wrote. For discrete things like images, filters work differently from what you probably know from a mathematical standpoint, where you mostly work on continuous functions. Using the responses from x- and y-filters to get the response from a tilted filter does not work exactly usually, there will be differences from using a filter that finds edges in your direction directly. – etarion Jun 12 '12 at 11:10
  • @etarion, I would very grateful if you provide and alternative to this solution. Correct me if Im wrong but arent the original filters x and y (the discrete result which we even start with), also approximations? If that is the case then I dont think another approximation from that is any more effective than nothing at all... – luhfluh Jun 12 '12 at 11:31
  • @etarion, all I see in your responses are criticism with no solution or alternative offered...the tool I built with this solution is working fine, albeit could be improved.with your solution – luhfluh Jun 12 '12 at 11:36
  • The "solution" was offered by Andrey a year ago - use a handmade kernel with cv::createLinearFilter (or the equivalent in the C API). I'm not saying what you do is wrong for your purpose, i'm just pointing out that there are subtle differences. It may very well be that you see no difference in practice. – etarion Jun 13 '12 at 08:48

2 Answers2

5

Hei. You can generally calculate any filter in any direction in the following way:

  1. resX = Calculate result on X direction
  2. resY = Caluclate result on Y direction
  3. Choose desired direction (angle alpha)
  4. The desired result is sqrt((Y*sin(alpha))^2 + (X*cos(alpha))^2)

This works for edge detection, motion blur and any linear directed filter.

DanielHsH
  • 4,287
  • 3
  • 30
  • 36
0

It does detect diagonals. You just run it twice. A point that is both horizontal and vertical is, by definition, diagonal.

john k
  • 6,268
  • 4
  • 55
  • 59