如何使用MATLAB使黑板上的文字看起来更清晰?

如果我想使最终图像更清晰,数字化外观,我应该放置哪些过滤器顺序。我的意思是只有两种不同的颜色,一种用于黑板,一种用于粉笔。

牧羊人nacy
浏览 532回答 3
3回答

阿波罗的战车

当要识别图像中的文本时,最好使用“ 笔划宽度变换”。这是我在您的图像上获得的一些结果(基本转换+不带过滤的连接组件): SWT转换图像我的mex实现基于此处的代码#include "mex.h"#include <vector>#include <map>#include <set>#include <algorithm>#include <math.h>using namespace std;#define PI 3.14159265struct Point2d {&nbsp; &nbsp; int x;&nbsp; &nbsp; int y;&nbsp; &nbsp; float SWT;};struct Point2dFloat {&nbsp; &nbsp; float x;&nbsp; &nbsp; float y;};struct Ray {&nbsp; &nbsp; Point2d p;&nbsp; &nbsp; Point2d q;&nbsp; &nbsp; std::vector<Point2d> points;};void strokeWidthTransform(const float * edgeImage,&nbsp; &nbsp; const float * gradientX,&nbsp; &nbsp; const float * gradientY,&nbsp; &nbsp; bool dark_on_light,&nbsp; &nbsp; float * SWTImage,&nbsp; &nbsp; int h, int w,&nbsp; &nbsp; std::vector<Ray> & rays) {&nbsp; &nbsp; // First pass&nbsp; &nbsp; float prec = .05f;&nbsp; &nbsp; for( int row = 0; row < h; row++ ){&nbsp; &nbsp; &nbsp; &nbsp; const float* ptr = edgeImage + row*w;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; for ( int col = 0; col < w; col++ ){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (*ptr > 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Ray r;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Point2d p;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p.x = col;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p.y = row;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r.p = p;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; std::vector<Point2d> points;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; points.push_back(p);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float curX = (float)col + 0.5f;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float curY = (float)row + 0.5f;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int curPixX = col;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int curPixY = row;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float G_x = gradientX[ col + row*w ];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float G_y = gradientY[ col + row*w ];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // normalize gradient&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float mag = sqrt( (G_x * G_x) + (G_y * G_y) );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (dark_on_light){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; G_x = -G_x/mag;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; G_y = -G_y/mag;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; G_x = G_x/mag;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; G_y = G_y/mag;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (true) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curX += G_x*prec;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curY += G_y*prec;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((int)(floor(curX)) != curPixX || (int)(floor(curY)) != curPixY)&nbsp; &nbsp; &nbsp;{&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curPixX = (int)(floor(curX));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; curPixY = (int)(floor(curY));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // check if pixel is outside boundary of image&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (curPixX < 0 || (curPixX >= w) || curPixY < 0 || (curPixY >= h)) {&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Point2d pnew;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pnew.x = curPixX;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pnew.y = curPixY;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; points.push_back(pnew);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( edgeImage[ curPixY*w+ curPixX ] > 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r.q = pnew;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // dot product&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float G_xt = gradientX[ curPixY*w + curPixX ];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float G_yt = gradientY[ curPixY*w + curPixX ];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mag = sqrt( (G_xt * G_xt) + (G_yt * G_yt) );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (dark_on_light){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; G_xt = -G_xt/mag;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; G_yt = -G_yt/mag;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; G_xt = G_xt/mag;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; G_yt = G_yt/mag;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (acos(G_x * -G_xt + G_y * -G_yt) < PI/2.0 ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float length = sqrt( ((float)r.q.x - (float)r.p.x)*((float)r.q.x - (float)r.p.x) + ((float)r.q.y - (float)r.p.y)*((float)r.q.y - (float)r.p.y));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (std::vector<Point2d>::iterator pit = points.begin(); pit != points.end(); pit++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float* pSWT = SWTImage +&nbsp; w * pit->y + pit->x;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (*pSWT < 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *pSWT = length;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *pSWT = std::min(length, *pSWT);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r.points = points;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rays.push_back(r);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ptr++;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;}bool Point2dSort(const Point2d &lhs, const Point2d &rhs) {&nbsp; &nbsp; return lhs.SWT < rhs.SWT;}void SWTMedianFilter(float * SWTImage, int h, int w,&nbsp; &nbsp; &nbsp; &nbsp; std::vector<Ray> & rays, float maxWidth = -1 ) {&nbsp; &nbsp; for (std::vector<Ray>::iterator rit = rays.begin(); rit != rays.end(); rit++) {&nbsp; &nbsp; &nbsp; &nbsp; for (std::vector<Point2d>::iterator pit = rit->points.begin(); pit != rit->points.end(); pit++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pit->SWT = SWTImage[ w*pit->y + pit->x ];&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; std::sort(rit->points.begin(), rit->points.end(), &Point2dSort);&nbsp; &nbsp; &nbsp; &nbsp; //std::nth_element( rit->points.begin(), rit->points.end(), rit->points.size()/2, &Point2dSort );&nbsp; &nbsp; &nbsp; &nbsp; float median = (rit->points[rit->points.size()/2]).SWT;&nbsp; &nbsp; &nbsp; &nbsp; if ( maxWidth > 0 && median >= maxWidth ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; median = -1;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; for (std::vector<Point2d>::iterator pit = rit->points.begin(); pit != rit->points.end(); pit++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SWTImage[ w*pit->y + pit->x ] = std::min(pit->SWT, median);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;}typedef std::vector< std::set<int> > graph_t; // graph as a list of neighbors per nodevoid connComp( const graph_t& g, std::vector<int>& c, int i, int l ) {&nbsp; &nbsp; // starting from node i labe this conn-comp with label l&nbsp; &nbsp; if ( i < 0 || i > g.size() ) {&nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; }&nbsp; &nbsp; std::vector< int > stack;&nbsp; &nbsp; // push i&nbsp; &nbsp; stack.push_back(i);&nbsp; &nbsp; c[i] = l;&nbsp; &nbsp; while ( ! stack.empty() ) {&nbsp; &nbsp; &nbsp; &nbsp; // pop&nbsp; &nbsp; &nbsp; &nbsp; i = stack.back();&nbsp; &nbsp; &nbsp; &nbsp; stack.pop_back();&nbsp; &nbsp; &nbsp; &nbsp; // go over all nieghbors&nbsp; &nbsp; &nbsp; &nbsp; for ( std::set<int>::const_iterator it = g[i].begin(); it != g[i].end(); it++ ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( c[*it] < 0 ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stack.push_back( *it );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c[ *it ] = l;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}int findNextToLabel( const graph_t& g, const vector<int>& c ) {&nbsp; &nbsp; for ( int i = 0 ; i < c.size(); i++ ) {&nbsp; &nbsp; &nbsp; &nbsp; if ( c[i] < 0 ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return i;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return c.size();}int connected_components(const graph_t& g, vector<int>& c) {&nbsp; &nbsp; // check for empty graph!&nbsp; &nbsp; if ( g.empty() ) {&nbsp; &nbsp; &nbsp; &nbsp; return 0;&nbsp; &nbsp; }&nbsp; &nbsp; int i = 0;&nbsp; &nbsp; int num_conn = 0;&nbsp; &nbsp; do {&nbsp; &nbsp; &nbsp; &nbsp; connComp( g, c, i, num_conn );&nbsp; &nbsp; &nbsp; &nbsp; num_conn++;&nbsp; &nbsp; &nbsp; &nbsp; i = findNextToLabel( g, c );&nbsp; &nbsp; } while ( i < g.size() );&nbsp; &nbsp; return num_conn;}std::vector< std::vector<Point2d> >&nbsp; &nbsp; &nbsp; &nbsp; findLegallyConnectedComponents(const float* SWTImage, int h, int w,&nbsp; &nbsp; &nbsp; &nbsp; std::vector<Ray> & rays) {&nbsp; &nbsp; std::map<int, int> Map;&nbsp; &nbsp; std::map<int, Point2d> revmap;&nbsp; &nbsp; std::vector<std::vector<Point2d> > components; // empty&nbsp; &nbsp; int num_vertices = 0, idx = 0;&nbsp; &nbsp; graph_t g;&nbsp; &nbsp; // Number vertices for graph.&nbsp; Associate each point with number&nbsp; &nbsp; for( int row = 0; row < h; row++ ){&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; for (int col = 0; col < w; col++ ){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; idx = col + w * row;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (SWTImage[idx] > 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Map[idx] = num_vertices;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Point2d p;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p.x = col;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p.y = row;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; revmap[num_vertices] = p;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; num_vertices++;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; std::set<int> empty;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.push_back(empty);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp; &nbsp; if ( g.empty() ) {&nbsp; &nbsp; &nbsp; &nbsp; return components; // nothing to do with an empty graph...&nbsp; &nbsp; }&nbsp; &nbsp; for( int row = 0; row < h; row++ ){&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; for (int col = 0; col < w; col++ ){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; idx = col + w * row;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( SWTImage[idx] > 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // check pixel to the right, right-down, down, left-down&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int this_pixel = Map[idx];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float thisVal = SWTImage[idx];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (col+1 < w) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float right = SWTImage[ w*row + col + 1 ];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (right > 0 && (thisVal/right <= 3.0 || right/thisVal <= 3.0)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g[this_pixel].insert( Map[ w*row + col + 1 ] );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g[ Map[ w*row + col + 1 ] ].insert( this_pixel );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //boost::add_edge(this_pixel, map.at(row * SWTImage->width + col + 1), g);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (row+1 < h) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (col+1 < w) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float right_down = SWTImage[ w*(row+1) + col + 1 ];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (right_down > 0 && (thisVal/right_down <= 3.0 || right_down/thisVal <= 3.0)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g[ this_pixel ].insert( Map[ w*(row+1) + col + 1 ] );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g[ Map[ w*(row+1) + col + 1 ] ].insert(this_pixel);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // boost::add_edge(this_pixel, map.at((row+1) * SWTImage->width + col + 1), g);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float down = SWTImage[ w*(row+1) + col ];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (down > 0 && (thisVal/down <= 3.0 || down/thisVal <= 3.0)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g[ this_pixel ].insert( Map[ w*(row+1) + col ] );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g[ Map[ w*(row+1) + col ] ].insert( this_pixel );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //boost::add_edge(this_pixel, map.at((row+1) * SWTImage->width + col), g);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (col-1 >= 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; float left_down = SWTImage[ w*(row+1) + col - 1 ];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (left_down > 0 && (thisVal/left_down <= 3.0 || left_down/thisVal <= 3.0)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g[ this_pixel ].insert( Map[ w*(row+1) + col - 1 ] );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g[ Map[ w*(row+1) + col - 1 ] ].insert( this_pixel );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //boost::add_edge(this_pixel, map.at((row+1) * SWTImage->width + col - 1), g);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; std::vector<int> c(num_vertices, -1);&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; int num_comp = connected_components(g, c);&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; components.reserve(num_comp);&nbsp; &nbsp; //std::cout << "Before filtering, " << num_comp << " components and " <<&nbsp; &nbsp; &nbsp;num_vertices << " vertices" << std::endl;&nbsp; &nbsp; for (int j = 0; j < num_comp; j++) {&nbsp; &nbsp; &nbsp; &nbsp; std::vector<Point2d> tmp;&nbsp; &nbsp; &nbsp; &nbsp; components.push_back( tmp );&nbsp; &nbsp; }&nbsp; &nbsp; for (int j = 0; j < num_vertices; j++) {&nbsp; &nbsp; &nbsp; &nbsp; Point2d p = revmap[j];&nbsp; &nbsp; &nbsp; &nbsp; (components[c[j]]).push_back(p);&nbsp; &nbsp; }&nbsp; &nbsp; return components;}enum {&nbsp; &nbsp; EIN = 0,&nbsp; &nbsp; GXIN,&nbsp; &nbsp; GYIN,&nbsp; &nbsp; DOLFIN,&nbsp; &nbsp; MAXWIN,&nbsp; &nbsp; NIN };void mexFunction( int nout, mxArray* pout[], int nin, const mxArray* pin[] ) {&nbsp; &nbsp; //&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; // make sure images are input in transposed so that they are arranged row-major in memory&nbsp; &nbsp; //&nbsp; &nbsp; mxAssert( nin == NIN, "wrong number of inputs" );&nbsp; &nbsp; mxAssert( nout > 1, "only one output" );&nbsp; &nbsp; int h = mxGetN( pin[EIN] ); // inputs are transposed!&nbsp; &nbsp; int w = mxGetM( pin[EIN] );&nbsp; &nbsp; mxAssert( mxIsClass( pin[EIN], mxSINGLE_CLASS ) && h == mxGetN( pin[EIN] ) && w == mxGetM( pin[EIN] ), "edge map incorrect");&nbsp; &nbsp; mxAssert( mxIsClass( pin[GXIN], mxSINGLE_CLASS ) && h == mxGetN( pin[GXIN] ) && w == mxGetM( pin[GXIN] ), "edge map incorrect");&nbsp; &nbsp; mxAssert( mxIsClass( pin[GYIN], mxSINGLE_CLASS ) && h == mxGetN( pin[GYIN] ) && w == mxGetM( pin[GYIN] ), "edge map incorrect");&nbsp; &nbsp; const float * edgeImage = (float*) mxGetData( pin[EIN] );&nbsp; &nbsp; const float * gradientX = (float*) mxGetData( pin[GXIN] );&nbsp; &nbsp; const float * gradientY = (float*) mxGetData( pin[GYIN] );&nbsp; &nbsp; bool dark_on_light = mxGetScalar( pin[DOLFIN] ) != 0 ;&nbsp; &nbsp; float maxWidth = mxGetScalar( pin[MAXWIN] );&nbsp; &nbsp; // allocate output&nbsp; &nbsp; pout[0] = mxCreateNumericMatrix( w, h, mxSINGLE_CLASS, mxREAL );&nbsp; &nbsp; float * SWTImage = (float*) mxGetData( pout[0] );&nbsp; &nbsp; // set SWT to -1&nbsp; &nbsp; for ( int i = 0 ; i < w*h; i++ ) {&nbsp; &nbsp; &nbsp; &nbsp; SWTImage[i] = -1;&nbsp; &nbsp; }&nbsp; &nbsp; std::vector<Ray> rays;&nbsp; &nbsp; strokeWidthTransform ( edgeImage, gradientX, gradientY, dark_on_light, SWTImage, h, w, rays );&nbsp; &nbsp; SWTMedianFilter ( SWTImage, h, w, rays, maxWidth );&nbsp; &nbsp; // connected components&nbsp; &nbsp; if ( nout > 1 ) {&nbsp; &nbsp; &nbsp; &nbsp; // Calculate legally connect components from SWT and gradient image.&nbsp; &nbsp; &nbsp; &nbsp; // return type is a vector of vectors, where each outer vector is a component and&nbsp; &nbsp; &nbsp; &nbsp; // the inner vector contains the (y,x) of each pixel in that component.&nbsp; &nbsp; &nbsp; &nbsp; std::vector<std::vector<Point2d> > components = findLegallyConnectedComponents(SWTImage, h, w, rays);&nbsp; &nbsp; &nbsp; &nbsp; pout[1] = mxCreateNumericMatrix( w, h, mxSINGLE_CLASS, mxREAL );&nbsp; &nbsp; &nbsp; &nbsp; float* pComp = (float*) mxGetData( pout[1] );&nbsp; &nbsp; &nbsp; &nbsp; for ( int i = 0 ; i < w*h; i++ ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pComp[i] = 0;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; for ( int ci = 0 ; ci < components.size(); ci++ ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for ( std::vector<Point2d>::iterator it = components[ci].begin() ; it != components[ci].end(); it++ ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pComp[ w * it->y + it->x ] = ci + 1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}Matlab函数调用笔划宽度转换(SWT)混合文件:function [swt swtcc] = SWT( img, dol, maxWidth )if size( img, 3 ) == 3&nbsp; &nbsp; img = rgb2gray(img);endimg = im2single(img);edgeMap = single( edge( img, 'canny', .15 ) );&nbsp;img = imfilter( img, fspecial('gauss',[5 5], 0.3*(2.5-1)+.8) );gx = imfilter( img, fspecial('prewitt')' ); %//'gy = imfilter( img, fspecial('prewitt') );gx = single(medfilt2( gx, [3 3] ));gy = single(medfilt2( gy, [3 3] ));[swt swtcc] = swt_mex( edgeMap.', gx.', gy.', dol, maxWidth ); %//'swt = swt'; %//'swtcc = double(swtcc'); %//'
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python