笔画宽度变化(C++和matlab算法)

最近一直在看工作方面的书籍,把论文的事情搁置了,之前承诺的贴代码的事一直拖。现在把代码整理发上来,只有核心部分的,都不是我写的,我是网上整理下载的,matlab代码的效果比较差。

全部文件网盘下载地址:http://pan.baidu.com/s/1qWwNMfM;

1.C++代码

下载地址:

需要先安装opencv和boost库。

boost库下载地址:http://www.boost.org/users/download/

boost的安装:http://www.cnblogs.com/pangxiaodong/archive/2011/05/05/2037006.html

装这个boost库,我只是把文件复制到vs安装目录的include文件夹下。

GitHub repository:https://github.com/aperrau/DetectText

2.matlab代码
function [ swtMap ] = swt( im, searchDirection )
%swt Preforms stoke width transform on input image
%   A novel image operator that seeks to find the value of stroke width
%   for each image pixel.  It‘s use is meant for the task of text
%   detection in natural images.
%
%   im = RGB input image of size m x n x 3
%   searchDirection = gradient direction is either 1 to detect dark text on light
%   background or -1 to detect light text on dark background.
%
%   swtMap = resulting mapping of stroke withs for image pixels

% Convert image to gray scale
im = im2double(rgb2gray(im));
%figure, imshow(im), title(‘Black and White Image‘);

% Find edges using canny edge dector
edgeMap = edge(im, ‘canny‘);
%figure, imshow(edgeMap), title(‘Edges Using Canny‘);

% Get all edge pixel postitions
[edgePointRows, edgePointCols] = find(edgeMap);

% Find gradient horizontal and vertical gradient
sobelMask = fspecial(‘sobel‘);
dx = imfilter(im,sobelMask);
dy = imfilter(im,sobelMask‘);
%figure, imshow(dx, []), title(‘Horizontal Gradient Image‘);
%figure, imshow(dy, []), title(‘Vertical Gradient Image‘);

% Initializing matrix of gradient direction
theta = zeros(size(edgeMap,1),size(edgeMap,2));

% Calculating theta, gradient direction, for each pixel on the image.
% ***This can be optimized by using edgePointCols and edgePointRows
% instead.***
for i=1:size(edgeMap,1)
    for j=1:size(edgeMap,2)
        if edgeMap(i,j) == 1
            theta(i,j) = atan2(dy(i,j),dx(i,j));
        end
    end
end

% Getting size of the image
[m,n] = size(edgeMap);

% Initializing Stoke Width array with infinity
swtMap = zeros(m,n);
for i=1:m
    for j=1:n
        swtMap(i,j) = inf;
    end
end

% Set the maximum stroke width, this number is variable for now but must be
% made to be more dynamic in the future
maxStrokeWidth = 350;

% Initialize container for all stoke points found
strokePointsX = zeros(size(edgePointCols));
strokePointsY = zeros(size(strokePointsX));
sizeOfStrokePoints = 0;

% Iterate through all edge points and compute stoke widths
for i=1:size(edgePointRows)
    step = 1;
    initialX = edgePointRows(i);
    initialY = edgePointCols(i);
    isStroke = 0;
    initialTheta = theta(initialX,initialY);
    sizeOfRay = 0;
    pointOfRayX = zeros(maxStrokeWidth,1);
    pointOfRayY = zeros(maxStrokeWidth,1);

    % Record first point of the ray
    pointOfRayX(sizeOfRay+1) = initialX;
    pointOfRayY(sizeOfRay+1) = initialY;

    % Increase the size of the ray
    sizeOfRay = sizeOfRay + 1;

    % Follow the ray
    while step < maxStrokeWidth
        nextX = round(initialX + cos(initialTheta) * searchDirection * step);
        nextY = round(initialY + sin(initialTheta) * searchDirection * step);

        step = step + 1;

        % Break loop if out of bounds.  For some reason this is really
        % slow.
        if nextX < 1 | nextY < 1 | nextX > m | nextY > n
            break
        end

        % Record next point of the ray
        pointOfRayX(sizeOfRay+1) = nextX;
        pointOfRayY(sizeOfRay+1) = nextY;

        % Increase size of the ray
        sizeOfRay = sizeOfRay + 1;

        % Another edge pixel has been found
        if edgeMap(nextX,nextY)

            oppositeTheta = theta(nextX,nextY);

            % Gradient direction roughtly opposite
            if abs(abs(initialTheta - oppositeTheta) - pi) < pi/2
                isStroke = 1;
                strokePointsX(sizeOfStrokePoints+1) = initialX;
                strokePointsY(sizeOfStrokePoints+1) = initialY;
                sizeOfStrokePoints = sizeOfStrokePoints + 1;
            end

            break
        end
    end

    % Edge pixel is part of stroke
    if isStroke

        % Calculate stoke width
        strokeWidth = sqrt((nextX - initialX)^2 + (nextY - initialY)^2);

        % Iterate all ray points and populate with the minimum stroke width
        for j=1:sizeOfRay
            swtMap(pointOfRayX(j),pointOfRayY(j)) = min(swtMap(pointOfRayX(j),pointOfRayY(j)),strokeWidth);
        end
    end
end

%figure, imshow(swtMap, []), title(‘Stroke Width Transform: First Pass‘);

% Iterate through all stoke points for a refinement pass.  Refer to figure
% 4b in the paper.

for i=1:sizeOfStrokePoints
    step = 1;
    initialX = strokePointsX(i);
    initialY = strokePointsY(i);
    initialTheta = theta(initialX,initialY);
    sizeOfRay = 0;
    pointOfRayX = zeros(maxStrokeWidth,1);
    pointOfRayY = zeros(maxStrokeWidth,1);
    swtValues = zeros(maxStrokeWidth,1);
    sizeOfSWTValues = 0;

    % Record first point of the ray
    pointOfRayX(sizeOfRay+1) = initialX;
    pointOfRayY(sizeOfRay+1) = initialY;

    % Increase the size of the ray
    sizeOfRay = sizeOfRay + 1;

    % Record the swt value of first stoke point
    swtValues(sizeOfSWTValues+1) = swtMap(initialX,initialY);
    sizeOfSWTValues = sizeOfSWTValues + 1;

    % Follow the ray
    while step < maxStrokeWidth
        nextX = round(initialX + cos(initialTheta) * searchDirection * step);
        nextY = round(initialY + sin(initialTheta) * searchDirection * step);

        step = step + 1;

        % Record next point of the ray
        pointOfRayX(sizeOfRay+1) = nextX;
        pointOfRayY(sizeOfRay+1) = nextY;

        % Increase size of the ray
        sizeOfRay = sizeOfRay + 1;

        % Record the swt value of next stoke point
        swtValues(sizeOfSWTValues+1) = swtMap(nextX,nextY);
        sizeOfSWTValues = sizeOfSWTValues + 1;

        % Another edge pixel has been found
        if edgeMap(nextX,nextY)
            break
        end
    end

    % Calculate stoke width as the median value of all swtValues seen.
    strokeWidth = median(swtValues(1:sizeOfSWTValues));

    % Iterate all ray points and populate with the minimum stroke width
    for j=1:sizeOfRay
        swtMap(pointOfRayX(j),pointOfRayY(j)) = min(swtMap(pointOfRayX(j),pointOfRayY(j)),strokeWidth);
    end

end

%figure, imshow(swtMap, []), title(‘Stroke Width Transform: Second Pass‘);

end

笔画宽度变化(C++和matlab算法)

时间: 2024-10-03 02:45:28

笔画宽度变化(C++和matlab算法)的相关文章

应用笔画宽度变换(SWT)来检测自然场景中的文本

Introduction: 应用背景:是盲人辅助系统,城市环境中的机器导航等计算机视觉系统应用的重要一步.获取文本能够为许多视觉任务提供上下文的线索,并且,图像检索算法的性能很大部分都依赖于对应的文本检测模块. 意义:传统的OCR应用于扫描文本,所以其依赖于把文本从背景像素中正确分离.这对于扫描文本来说是很简单的,但是自然图像由于存在色彩噪声,模糊,遮挡,很难将文本从背景中分离. 文章提出的方法:文本有着固定的笔画宽度,利用这一特性就够从背景中将其恢复.首先求图像的笔画宽度变换即每个像素都分配了

基于笔画宽度变换的自然场景文本检测方法

依据:自然场景中的文字笔画倾向于固定的宽度. 检测流程如下图: 笔画宽度的算法如下: 首先将图像中每个像素的笔画宽度值设置为无穷大. (1)利用边缘检测算子(Canny)对图像I(x,y)进行边缘检测,可以得到每个边缘像素点都具有一个方向梯度值: (2)假设p为一个边缘像素点,Dp为其梯度方向,按照梯度方向沿着路线r=p+Dp*n(n>=0)寻找另一个边缘象素点q,Dq为这个像素点的梯度方向,Dp和Dq方向相反: 在这个步骤中,如果没有找到q或者二者的梯度方向不是相反的,则重新寻找:找到之后计算

自然场景文本识别:基于笔画宽度变换的文本检测

最近在学习自然场景(Natural Scenes)的文本识别(Text Recognition)问题,这一问题也是时下一个非常热门的亟待解决的问题.在阅读学习了一定量的文献资料之后,有了一定收获,本文提到的基于"笔画宽度变换"(Stroke Width Transform)的方法,是目前个人看到比较认同的方法. 对于自然场景的文本识别,一个很重要的问题就在于如何从自然场景的图片中检测与定位出文本信息,考虑到文本的结构.像素.几何变形.背景复杂度.图像分辨率等多种问题带来的干扰,对于文本

【转】 自然场景文本识别:基于笔画宽度变换的文本检测

最近在学习自然场景(Natural Scenes)的文本识别(Text Recognition)问题,这一问题也是时下一个非常热门的亟待解决的问题.在阅读学习了一定量的文献资料之后,有了一定收获,本文提到的基于“笔画宽度变换”(Stroke Width Transform)的方法,是目前个人看到比较认同的方法. 对于自然场景的文本识别,一个很重要的问题就在于如何从自然场景的图片中检测与定位出文本信息,考虑到文本的结构.像素.几何变形.背景复杂度.图像分辨率等多种问题带来的干扰,对于文本的检测着实

在.NET中应用MATLAB算法

在科学研究和工程应用中,往往要进行大量的数学计算,其中包括矩阵运算.这些运算一般来说难以用手工精确和快捷地进行,而要借助计算机编制相应的程序做近似计算.目前流行用Basic.Fortran和c语言编制计算程序, 既需要对有关算法有深刻的了解,还需要熟练地掌握所用语言的语法及编程技巧.对多数科学工作者而言,同时具备这两方面技能有一定困难.通常,编制程序也是繁杂的,不仅消耗人力与物力,而且影响工作进程和效率.为克服上述困难,美国Mathwork公司于1967年推出了"Matrix Laborator

边缘检测matlab算法汇总

边缘检测matlab算法汇总 1.      基于一阶微分算子检测边缘图像 一阶微分边缘算子又称梯度边缘算子,它是利用图像在边缘处的阶跃性,及图像梯度在边缘去得极大值得特征性进行边缘检测. Sobel算子:image =edge(in_image,'sobel',threshold,direction); Prewitt算子: image = edge(in_image,'prewitt',threshold,direction); Roberts算子: image = edge(in_imag

将caffe训练时loss的变化曲线用matlab绘制出来

1. 首先是提取 训练日志文件; 2. 然后是matlab代码: clear all; close all; clc; log_file = '/home/wangxiao/Downloads/43_attribute_baseline.log'; fid = fopen(log_file, 'r'); fid_accuracy = fopen('/home/wangxiao/Downloads/output_accuracy.txt', 'w'); fid_loss = fopen('/hom

根据屏幕转向方向和屏幕宽度变化改变UITableView显示效果 屏幕旋转

获取屏幕转向和根据转向方向设置宽度: 1.获取屏幕转向事件: [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rotateScreen) name:UIDeviceOrientationDidChangeNotification object:nil]; [NSNotificationCenter defaultCenter]:事件中心对象: addObserver:self :添加到哪个对象:

[Matlab]算法工匠视频1:数字信号处理仿真及实现 第一讲 信号源的产生和滤波1、2

需要配合教学视频食用: %欢快版本 https://www.bilibili.com/video/av17343551 https://www.bilibili.com/video/av17707835 %严肃版本 https://www.bilibili.com/video/av16683579 课程相关代码: % % 算法工匠 信号源的产生和滤波1 % firdesign.m % author:照着抄的 作者是up主. % 2018年6月3日 18:12:35 clear ; close a