📜 ⬆️ ⬇️

Program for digitizing graphs, drawings, drawings: algorithms for the project “Tutor: Mathematics”


Content


opening speech
Principle of operation
Program description
Final program code
Advantages of working with digitized functions with examples
Epilogue



opening speech


In various fields related to science and education, engineering encounters a task related to obtaining data from graphs created at the time when digital media did not exist, or real data for which graphs were created were lost, or, finally, the schedule is the final form of work of some devices that do not give a set of coordinates of points in an explicit form.

In order to get data, you need to “ digitize ” such a graph (or graphic object), in other words, you need to get a set of abscissas and ordinates of the graph points - then you can perform various manipulations on them: build a new (qualitative) graph, perform calculations, translating it into a new format (for example, building a spline), etc.
')
In the project " Tutor: Mathematics " (read the article on Habrahabr - "Tutor: Mathematics" to prepare for the EGE and CDF - from idea to release. A story about a unique educational project ) we met this problem in two main ways:


This post contains the code for the graphicsDigitizing function created for this, and also briefly describes how it works. You can also see how it works live .

Principle of operation


The work of the program is quite simple. It is necessary to put a digital illustration (scan, photo, screenshot, another picture) on some field on the “first” layer. Then it is processed manually:


We chose B-splines for several reasons:


The figure below shows a set of points (control points), a set of B-splines of the 1st, 2nd and 3rd degrees, as well as a Bezier curve (in the case shown, this is essentially a B-spline of the 7th degree).



To create a program for digitizing graphs - like for many other tasks - we use the Wolfram Language .

Program description


Of course, we will not describe how the entire code of the program presented below works in steps, it would be very long and, as it seems to us, those who are interested in the issue under consideration or, moreover, those whom he is acutely aware of will be able to understand in all the "cogs" of the code, good, it is short.

We will pay attention to its main elements.

Let's start with a set of functions that will be required for implementation. You can look at what each of them does in the documentation:

CompoundExpression , ClearAll , SetDelayed , Optional , Pattern , Blank , Image , ImageResize , List , Rule , ColorSpace , With , Set , ImageDimensions , CreateDialog , ExpressionCell , DynamicModule , Grid , DefaultButton , DialogReturn , If , Less , Length , None , Drop , Transpose , Part , Span , ReplaceAll , Rescale , All , Min , Max , RuleDelayed , Real , Round , CopyToClipboard , BSplineCurve , SplineDegree , TabView , Row , Slider , Dynamic , Times , Pi , Power , ImageSize , Small , Slider2D , SetterBar , InputField , FieldSize , Alignment , Left , Spacings , Automatic , LocatorPane , Framed , Graphics , Inset , Cos , Sin , EdgeForm , Directive , AbsoluteThickness , RGB Color , Opacity , Yellow , Rectangle , Dashed , Blue , PlotRange , Plus , LocatorAutoCreate , True , Center , Top , Axes , AspectRatio , Initialization , Null , Condition , String , FileExists , Import , BlankNullSequence , Echo , Inactive , Nothing

One of the main functions in the work of this program is the DynamicModule function for creating interactive spaces and objects. With its help, the "revival" of the whole structure occurs.

The Grid function is necessary for organizing space - it allows you to build tables of various shapes and place content in their cells: texts, sliders, illustrations, interactive objects, etc.

The LocatorPane , Slider , Slider2D , InputField functions are used to make interactive elements — a field with a selection of points, sliders (one- and two-dimensional, respectively), a text input field (for the function definition area).

To “draw” graphic primitives, use the Graphics function (and, if necessary in 3D, use Graphics3D ).

And, of course, the most important here is the BSplineCurve function, which allows you to represent a set of points as a finished B-spline curve.



In the video below you can see how the program works live:



Final program code


The final function is actually not as great as it might seem. Although this, of course, a direct consequence of the great opportunities Wolfram Language:

View code


ClearAll[graphicsDigitizing]; graphicsDigitizing[image_Image: ImageResize[Image[{{{1,1,1}}},ColorSpace->"RGB"],{600,600}]]:=With[ {im=ImageResize[image,600]}, With[ {imdim=ImageDimensions[im]}, CreateDialog[{ ExpressionCell[ DynamicModule[ {degree,xmin=0,xmax=1,ymin=0,ymax=1,currentFunction,u,unew,udiap,\[Alpha],\[Beta]1,\[Beta]2}, Grid[ { { DefaultButton[ "    ", DialogReturn[ With[ {var1=If[ Length[u]<4, None, unew=Drop[u,2]; udiap=Transpose[u[[1;;2]]]; Transpose[ { Rescale[unew[[All,1]],{Min[udiap[[1]]],Max[udiap[[1]]]},{xmin,xmax}], Rescale[unew[[All,2]],{Min[udiap[[2]]],Max[udiap[[2]]]},{ymin,ymax}]} ]/.x_Real:>Round[x,0.01]],var2=degree}, CopyToClipboard[BSplineCurve[var1,SplineDegree->var2]]] ]] }, { TabView[ {""->Grid[ { { Grid[ { { Row[{" :",Slider[Dynamic@\[Alpha],{-Pi/6,Pi/6},ImageSize->Small]}," "] }, { Row[{":",Slider2D[Dynamic[\[Beta]1],{0.2 Max[imdim] {-1,-1},0.2 Max[imdim] {1,1}}],Slider2D[Dynamic[\[Beta]2],{0.2 Max[imdim] {-1,-1},0.2 Max[imdim] {1,1}}]}," "] }, { Row[{" :",SetterBar[Dynamic@degree,{0,1,2,3,4}]}," "] }, { Grid[{{"\!\(\*SubscriptBox[\(x\), \(min\)]\) =", InputField[Dynamic[xmin],FieldSize->{3,1}],"\!\(\*SubscriptBox[\(x\), \(max\)]\) =", InputField[Dynamic[xmax],FieldSize->{3,1}]},{"\!\(\*SubscriptBox[\(y\), \(min\)]\) =", InputField[Dynamic[ymin],FieldSize->{3,1}],"\!\(\*SubscriptBox[\(y\), \(max\)]\) =", InputField[Dynamic[ymax],FieldSize->{3,1}]}}] }}, Alignment->Left, Spacings->{Automatic,1}], LocatorPane[ Dynamic@u, Framed@Dynamic@Graphics[{Inset[im,{0,0},{0,0},imdim,{Cos[\[Alpha]],Sin[\[Alpha]]}], {EdgeForm[Directive[AbsoluteThickness[3],RGBColor[{214,0,0}/255]]], Opacity[0.2,Yellow], Rectangle[u[[1]],u[[2]]]}, {Dashed,Blue,AbsoluteThickness[4], If[Length[u]<4,BSplineCurve[u[[1;;2]],SplineDegree->2],BSplineCurve[Drop[u,2],SplineDegree->degree]] }}, PlotRange->Transpose[{\[Beta]1,imdim+\[Beta]2}],ImageSize->600],LocatorAutoCreate->True] } },Alignment->{Center,Top} ], ""->Dynamic@Graphics[ {Blue,AbsoluteThickness[2], If[Length[u]<4, BSplineCurve[u[[1;;2]],SplineDegree->2], BSplineCurve[unew=Drop[u,2]; udiap=Transpose[u[[1;;2]]]; Transpose[ {Rescale[unew[[All,1]],{Min[udiap[[1]]],Max[udiap[[1]]]},{xmin,xmax}], Rescale[unew[[All,2]],{Min[udiap[[2]]],Max[udiap[[2]]]},{ymin,ymax}]}], SplineDegree->degree]]}, PlotRange->{{xmin,xmax},{ymin,ymax}}, ImageSize->600, Axes->True, AspectRatio->imdim[[2]]/imdim[[1]]] },Alignment->Center] } } ], Initialization:>(u={{0,0},imdim};\[Alpha]=0; degree=3;\[Beta]1=0.1 Max[imdim] {-1,-1};\[Beta]2=0.1 Max[imdim] {1,1})] ]}];]]; graphicsDigitizing[image_String/;FileExistsQ[image]]:=graphicsDigitizing[Import[image]]; graphicsDigitizing[x___]:=(Echo[Inactive[graphicsDigitizing][x],"  : "]; Nothing) 

Advantages of working with digitized functions with examples


Naturally, with the graphics before digitizing, any work is extremely difficult, however, after you have digitized the schedule, say, with the help of our program, you can already do a lot. Let us show some examples.

For example, let the schedule be given:



Let's digitize it (see video above ) and make calculations.

For a start, just replace the head part of the expression obtained during the operation of the program from BSplineCurve with BSplineFunction , which builds an analytical expression with which you can already perform calculations:



The only drawback is that such a function is normalized to 1, that is, the function f (t), when t is changed from 0 to 1, runs through all its values, which are B-spline points:



However, this is easy to deal with. It is enough to construct an interpolation polynomial:



After that, you can do anything.

Build a graph, say, from 1 to 9:



Integrate the function across the entire task area:



Build a graph of the derivative:



Find the length of the curve:



Or the analytical representation of the curve (in parametric form):


Code with an illustration
 pts=Rationalize[{{0.01`,10.92`},{0.19`,16.36`},{0.34`,20.76`},{0.55`,25.17`},{0.96`,29.57`},{1.9100000000000001`,34.49`},{2.74`,38.63`},{3.38`,42.09`},{3.97`,44.03`},{4.47`,49.77`},{4.88`,56.5`},{5.29`,63.24`},{5.65`,69.19`},{6.0600000000000005`,74.63`},{6.53`,78.52`},{7.0200000000000005`,83.96000000000001`},{7.46`,86.55`},{8.02`,89.4`},{8.26`,86.55`},{8.67`,82.4`},{9.21`,80.85000000000001`},{9.57`,79.81`},{9.93`,79.81`}},1/100]; ptsL=Length[pts]; splineDegree=3; knots=ConstantArray[0,splineDegree]~Join~Subdivide[ptsL-splineDegree]~Join~ConstantArray[1,splineDegree]; FullSimplify@Simplify[ Sum[ pts[[i+1]]PiecewiseExpand[BSplineBasis[{splineDegree,knots},i,t]], {i,0,ptsL-1}] ] 

And you can, of course, simply improve the original schedule:



Epilogue


We hope that the story about the digitization function will be useful to you and you can use our algorithm. Ahead, as we promised in the previous article, you will find many more new stories about our application and algorithms that are under his hood.

An article of their series of articles on the project " Tutor: Mathematics " to prepare for the EGE and the CDF.

Source: https://habr.com/ru/post/351068/


All Articles