I have the following image: and I'd like to detect a contour of the note which is intuitionally seen easy, but when I try to do it, it actually isn't that easy.
For quick prototyping I started using MATLAB first (but later I want to do it in Java thus I'd like to not use too many special algorithms in MATLAB but rather try to use basic image proessing algorithms (prewitt / sobel / canny / adaptive thresholds / hough trafo) which are easily available in another language as well (e.g. opencv etc)..
The most easy code to start with was (but I thought this should already be quite good as the outside-edge looks to strong compared to the inside ones):
I = double(rgb2gray(imread('img.jpg')));
bw = edge(I, 'canny');
imshow(bw)
I thought matlab would be doing the choice of the threshold in the canny filter very well when using the automatical-mode. But it actually doesn't: https://i.sstatic.net/wrry6.png
When setting the threshold as a scalar manually (to .4 e.g.) I still get way too many gradients for the text inside and the outside borders are already way too incomplete/patchy: https://i.sstatic.net/kiY5F.png
I tried it using a prewitt filter (in x and y direction):
I = double(rgb2gray(imread('img.jpg')));
f1 = double(fspecial('prewitt'));
x = conv2(I, f);
y = conv2(I, f');
bw = (x.^2+y.^2).^0.5;
colormap(gray(256))
imagesc(bw);
resulting in: https://i.sstatic.net/FyUCS.png so also not very well... it looks better but still the outside is very patchy :(
Any ideas how to improve it very much? Further I'd like to unwarp the image later on to a rectangular shape. Any ideas on how to do it? Hough transform wouldn't work on a non-straight contour like the image above as it yields straight lines as a result...
Thanks very much!
Edit: Okay I found out the patchy-look comes from MATLAB... when zooming in, it is much much better and less patchy, see: https://i.sstatic.net/JfewK.jpg And I could imagine to find the contour by shrinking the outer contour because it is all black in this case (some sort of boundary box). But I don't want to assume that as the pictures are not always taken with flashlight on, e.g.: https://i.sstatic.net/Gqhyy.jpg So then there will be some noise in the outer areas...
Edit2: Just found Algorithm to detect corners of paper sheet in photo doesn't look too easy obviously. :) Maybe you've got some new ideas to start with.
Here is prototype in C++:
#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdarg.h>
#include "opencv2/opencv.hpp"
#include "fstream"
#include "iostream"
using namespace std;
using namespace cv;
//-----------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------
int main( int argc, char** argv )
{
namedWindow("Img");
Mat Img=imread("Test2.JPG",0);
cv::resize(Img,Img,Size(Img.cols/8,Img.rows/8));
cv::threshold(Img,Img,100,255,cv::THRESH_OTSU);
cv::dilate(Img,Img,cv::Mat::ones(3,3,CV_8UC1));
cv::erode(Img,Img,cv::Mat::ones(23,23,CV_8UC1));
cv::resize(Img,Img,Size(Img.cols*8,Img.rows*8));
imshow("Img",Img);
waitKey(0);
return 0;
}
It gives the output image (after that just find contours).