3

I'm new to this community, and to R, but not new to programming (C, VB, Matlab, APDL etc). I'm creating an engineering evaluation tool for a product, that needs to quantify the quality of the edge of a vane. I'll be evaluating hundreds of such vanes using an automated platform with a webcam in exactly the same place each time - thus will be performing statistical image analysis. I'm not new to statistics, but am completely new to R and digital image processing. (I selected R, since it's free, and I should be able to script in it. If there's a better way to do this, please let me know. Matlab is 2nd choice, because of the cost.)

An original image is shown here: Link

Some basic scripting later:

library(EBImage) original=readImage("original.jpg") fhi=matrix(1,nc=3,nr=3) fhi[2,2]=-8 filtered=filter2(original,fhi) 

I selected the EBImage library, based on some initial reading online. Suggest alternatives, if better please.

Filtered image looks like this: Link

What I need to do:

  1. Get the X,Y coordinates of all points on 'Edge 2', that lie between 'Edge 1' and 'Edge 3'. The X,Y origin can be assumed to be the lower left corner of the photo, although, ideally I'd like it to be the intersection of Edge 1 and Edge 2.
  2. Store X,Y coordinates in a matrix with an identifier for the vane number. ("Vane 1", "Vane 2", or just 1,2,... etc)

I'm quite lost on how I proceed from where I am. Appreciate any pointers.

2
  • What defines the quality of a vane? Straightness? Something else? And what will you do with the X, Y coordinates as the next step of processing? Commented Jul 26, 2014 at 19:25
  • Mark, there's quite a bit that will be done with the X Y coordinates - comparison of each vane within the component (visually, basic statistics), comparison within each product family, effect of tolerance stack up / defect showing itself on one side of the comp vs the other... the list goes on. Once I have the raw X,Y data, the possibilities are plenty. Commented Jul 26, 2014 at 19:45

2 Answers 2

1

I kind of liked the Canny edge detection in ImageMagick, and got the following from your input photo, using this command:

convert photo.jpg -canny 0x12+10%+30% out.jpg 

enter image description here

I then had a try with HoughLinesP from OpenCV, and got the image below:

enter image description here

Using this code which is heavily borrowed from the OpenCV website:

#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> using namespace cv; using namespace std; int main(int argc, char** argv) { const char* filename = argc >= 2 ? argv[1] : "in.jpg"; Mat src = imread(filename, 0); if(src.empty()) { cout << "can not open " << filename << endl; return -1; } Mat dst, cdst; dst=src; cvtColor(src, cdst, CV_GRAY2BGR); vector<Vec4i> lines; HoughLinesP(dst, lines, 1, CV_PI/90, 150, 300, 50 ); printf("Lines detected: %d\n",(int)lines.size()); for( size_t i = 0; i < lines.size(); i++ ) { Vec4i l = lines[i]; line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA); } imshow("source", src); imshow("detected lines", cdst); waitKey(); return 0; } 

ADDITIONAL MATERIAL

Thanks to @dlemstra for the input about ImageMagick supporting HoughLines too, with that advice, I did the following in s single invocation of ImageMagick (without using OpenCV):

convert photo.jpg \ \( +clone -canny 0x5+10%+30% -write photo_canny.jpg \ -background none -fill red -stroke red -strokewidth 2 \ -hough-lines 9x9+150 -write photo_lines.jpg \) -composite photo_hough.jpg 

And it looks like this:

enter image description here

I wonder about rotating the image after finding the long upright edge so that it is vertical and then cutting the image along that line and looking for the horizontal edge at bottom left either using different parameters or after stretching the width of the image to emphasize the horizontal line...

Sign up to request clarification or add additional context in comments.

6 Comments

New versions of ImageMagick also support 'Hough lines'.
@dlemstra Many thanks for sharing your knowledge - I have updated accordingly.
Wow, thanks @MarkSetchell. Lots of good info here. I'll take some time to process this and see how I can implement this in my codes. Many thanks again.
Great sharing! I'm following the same topic, too. Would like to follow up. 1. How to induce the opencv code into R and make use of it in R? 2. Is there Hough Circle Detection function available in R, or anything can be induced in R. Thanks
@Grec001 Sorry, I know very little about R - in fact you could write everything I know about R on a postage stamp - with a fat marker pen!
|
1

This is the best I managed to do with finding coordinates of edges. This is a pretty coarse approach, but it should give you some ideas. Let me preface this by saying I know pretty much nothing about image processing. So, one can likely do a lot better with the edge detecting than I did. I used the biOps package.

library(biOps) original <- readJpeg("original.jpg") # I did not try hard to detect edges as I don't know what I'm doing. # If you can do better on the edge detecting, you'll get better results test <- imgHomogeneityEdgeDetection(imgCanny(original, 2)) # did this to work with one of the three (i.e. red, green, blue) reds <- imgRedBand(test) # reds only contains values 32 and 255. 255 is "edges" # find the indices of the "edges" edgelocations <- which(reds!=32, arr.ind=TRUE) 

The origin starts in the upper left corner of the original image. See plot(edgelocations).

So, you can flip it to change the origin:

edgelocations <- which(t(r)[,nrow(r):1]!=32, arr.ind=TRUE) plot(edgelocations) 

enter image description here

1 Comment

Many many thanks @Frank. I'll process this and see how I can utilize this.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.