Reputation: 2759
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:
I'm quite lost on how I proceed from where I am. Appreciate any pointers.
Upvotes: 3
Views: 1472
Reputation: 17611
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)
Upvotes: 1
Reputation: 207345
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
I then had a try with HoughLinesP from OpenCV, and got the image below:
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:
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...
Upvotes: 1