我有以下图像:而且我想检测直觉上看起来很简单的音符轮廓,但是当我尝试这样做时,实际上并不是那么容易。
为了快速进行原型(prototype)制作,我首先开始使用MATLAB(但后来我想在Java中使用它,因此我不想在MATLAB中使用太多特殊算法,而尝试使用基本的图像处理算法(prewitt / sobel / canny /自适应阈值) / hough trafo),也很容易用另一种语言(例如opencv等)获得。
最容易开始的代码是(但是我认为这应该已经很好了,因为与内部相比,外部边缘看起来更坚固):
I = double(rgb2gray(imread('img.jpg')));
bw = edge(I, 'canny');
imshow(bw)
我认为使用自动模式时,matlab会很好地在canny滤波器中选择阈值。但实际上并没有:http://i.imgur.com/LeKPgso.png
当手动将阈值设置为标量时(例如,设置为.4),对于内部文本和外部边界而言,我仍然得到太多的渐变,太不完整/不完整:http://i.imgur.com/p68CVIU.png
我尝试使用prewitt过滤器(在x和y方向上):
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);
结果是:http://i.imgur.com/Jd9Fqpn.png也不太好...
它看起来更好,但外面仍然很不整洁:(
有什么想法可以大大改善它吗?
此外,我想稍后将图像变形为矩形。关于如何做的任何想法?像上面的图像一样,霍夫变换不适用于非直线轮廓,因为它会产生直线。
非常感谢!
编辑:好的,我发现斑驳的外观来自MATLAB。。。放大时,效果要好得多,斑点也更少,请参见:http://i.imgur.com/UrPd8me.png
我可以想象通过缩小外部轮廓来找到轮廓,因为在这种情况下它是黑色的(某种边界框)。但我不想假设由于图片并非总是在手电筒打开的情况下拍摄,例如:http://i.imgur.com/nfqygmA.jpg
所以外面会有些噪音...
Edit2 :刚找到的Algorithm to detect corners of paper sheet in photo
看起来不太容易。 :)也许您有一些新的想法开始。
最佳答案
这是C++的原型(prototype):
#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;
}
它给出了输出图像(此后仅找到轮廓)。