我有几个样本,从彩色图像,我应该变成二进制。利用自适应阈值,取得了最佳的效果。
数字是非常好的,明确的定义,但周围是嘈杂的,这些“垂直线”分隔每个数字最终被读取为一个数字1的OCR工具,例如。
然后我注意到,在数字周围,图像是干净的。我想,如果我能只剪掉数字(在黑白画之前还是之后)?然后“粘贴”这些数字的白色背景。
我试着使用侵蚀和扩张,但仍然有许多剩余的“点”。如果我能做到我的想法(以上),它将减少侵蚀/扩张,并增加“清洁”的数字在削减之前,我不知道。
这有可能吗?我说得通吗?如果是,我如何使用OpenCV来做到这一点?有什么建议吗?
我正在使用的一些图片:




注:上面的图像并没有经历侵蚀和/或膨胀、自适应阈值的过程。
更新:
@Mahm00d,我试了一下你用第一个图像说的话,得到了下面的图像,这很好,但是前两个数字的反射问题还在继续。有办法解决这个问题吗?我应用了自适应阈值,但图像仍然存在相当大的噪声。
GaussianBlur +带有OTSU标志的Treshold:

GaussianBlur +自适应阈值:

发布于 2013-11-29 08:33:12
通常最好先使用一些去噪技术,比如在进行阈值和形态学之前使用高斯/中值模糊:
(Java代码)
Imgproc.cvtColor(inputMat, gMat, Imgproc.COLOR_RGB2GRAY);
// Gaussian blur : 21x21 window, sigma = 50.0 (select these accordignly)
Imgproc.GaussianBlur(gMat, gMat, new Size(21.0, 21.0), 50.0);
// Otsu thresholding (or any other thresholding techinique...)
Imgproc.threshold(gMat, gMat, 0, 255, Imgproc.THRESH_OTSU | Imgproc.THRESH_BINARY);你的产出:

以上代码输出:

更新:
这些问题往往需要一些参数值的处理,才能得到一个好的结果,并得到最优的值。对于第二个图像,下面是我使用的代码(自适应阈值)以获得更好的结果:
Imgproc.GaussianBlur(inImg, inImg, new Size(21.0, 21.0), 50.0);
Imgproc.adaptiveThreshold(inImg, inImg, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 111, -20);结果:

当然,这并不完美,但至少反射被移除了。此外,形态过程可以帮助产生更好的结果。
发布于 2013-11-29 08:21:55
一种解决方案是应用膨胀和侵蚀,找出小于X像素的所有轮廓,并用白色填充它们:
int main()
{
// Load the image as a Grayscale
Mat image = imread("image.jpg", CV_LOAD_IMAGE_GRAYSCALE);
// Threshold the image
image = image > 120;
// Create bigger image with image width and height + 10 pixels
Mat image_big = Mat::zeros( image.size().height + 10, image.size().width + 10, CV_8UC1 );
// Set bigger image to be all white
image_big.setTo(255);
Mat image_big_copy;
// This may vary, you must find it for yourself
// Dilate image 4 times and erode once
dilate(image, image, Mat(), Point(-1,-1), 4);
erode(image, image, Mat(), Point(-1,-1));
// Copy image in the center of bigger image so you left 5px around image blank/white
// Create a new ROI that points to center of the bigger image
Mat image_big_roi = image_big( Rect(Point(5, 5), Size(image.size())) );
// Copy image to the bigger image ROI
addWeighted(image_big_roi, 0., image, 1., 0., image_big_roi);
// Create a data copy of image_big
image_big.copyTo(image_big_copy);
// Find all contours in a given image and store them in contours
vector<vector<Point> > contours;
findContours(image_big_copy, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
for( int i = 0; i < contours.size(); i++ )
{
// This is your condition to filter out unwanted contours etc.
// For every contour if its area is bigger/smaller than the sum of pixels
if ( fabs(contourArea(Mat(contours[i]))) < 800 )
{
// Fill a contour with white color
drawContours(image_big, contours, i, Scalar(255), CV_FILLED);
}
}
imshow("Image original", image);
imshow("Image edited", image_big);
waitKey(0);
return 0;
}原始图像:

之后:

https://stackoverflow.com/questions/20277954
复制相似问题