How to cut out numbers from an image dynamically? - vb.net

i've got to this stage:
where i can find the numbers in the above image but i need to cut them out so i can retain the order etc. but the as the number increases the spacing changes and the position of the number?
so i think it should be a find a white PX the continue until it find a solid black col and then use the points to do a simple cut any help would be great.

A simple solution would be this:
Find the first upmost horizontal line which contains white pixels
From that line find the first horizontal line which contains only black pixels
Those two lines are your upper and lower borders.
Between this borders proceed like this:
Find the first most left vertical line which contains white pixels
From that line find the last vertical line which contains only black pixels and which comes directly after a line with white pixels.
Those two lines are your left and right borders.
The steps to separate single numbers can be performed analogously.
If you need to identify which numbers are in your picture, I recommend using specialized computer vision libraries.
Some VB.net pseudo code to get you going:
Sub FindTopBorder(image As MyImage) As Integer
For y = 0 to image.Height - 1
For x = 0 to image.Width - 1
Dim pixel = image.GetPixel(x, y)
If ('Check if pixel is white here with RGB or Color') Then
Return y
End If
Next
Next
' Just in case there are no white pixels or use an exception instead
Return -1
End Sub

I would start looking into Connected component segmentation. You find a pixel which is within a character (number). Then run the connected component algorithm which finds all connected pixels under specific set of rules (e.g. slight deviation in color, stop at hard borders etc).
http://en.wikipedia.org/wiki/Connected-component_labeling
If you can use libraries, I'm sure OpenCV or similar libraries support this out of the box.
//edit
I see you need VB.net. Probably it is easiest to port some algorithm to VB or create one yourself.
See e.g. http://www.codeproject.com/Articles/336915/Connected-Component-Labeling-Algorithm
What to expect
Input
An image containing two shapes:
Output
Now each is separated into single images.

Related

Add text box at specific location in report base on value

I'm working on a cut list generator but I'm having difficulty on the final report. I'd like to display a rectangle that represents the factory length piece with lines indicating cut points. In each segment I'd like to have the length of the piece shown. Using Report.line I've created the rectangles needed but I'm not sure how to get text in each box. Here is a sample output so far As an example I want the three rectangles for Piece #1 to have 48" in them, probably all the way to the left. Any suggestions? I thought createReportControl might work but I'm not sure that is the correct approach. I'm also thinking about one text box with a monospace font so I can scale the input across the entire width. Any suggestions are appreciated.
Thanks,
Dave
I played around with the monospace font idea. It isn't as pretty as I would like but I'm getting closer.
The issue is that I cannot keep the text in the same spot in each box. There is one line lower on the page that pushes the number almost out the right side of the box.
Sample Output
This code is functional but I'm looking at the cosmetics. I'm inserting spaces between my values using the following function:
Private Function InsertSpaces(CutLen, PieceLen) As String
MaxChar = 50 ' 6 inch 14pt Courier text box
cutchar = Int(CutLen / PieceLen * MaxChar)
Cutcharcount = Len(Str(CutLen))
cutchar = cutchar - Cutcharcount + 1
For i = 1 To cutchar
InsertSpaces = InsertSpaces + " "
Next
End Function
I'm just trying to clean it up. CreateReportControl was giving me a error because I wasn't in design mode. I'm guessing that is because it ran as part of OnFormat of the Detail section.

How to add two images together (green screen system) in LabVIEW

I have two images, one with subject and other one with background. The subject image has green background and I want to remove the green color from subject and add the subject without green color to another background, basically changing the background of one picture with another in LabVIEW without C code or MATLAB code, only using LabVIEW blocks.
So far, I got the following, but I am not getting one thing how to remove a very small portion of pixels. How to solve this problem,
So your algorithm is to replace a pixel, when red - blue =0 in the first place.
This condition is true for all this colors:
While there is no magenta in the picture, there is some almost black below the elbow and some almost white at the hand. So, that's replaced.
Try to restrict the colors to be replaced more, maybe like this:
Also, I'd to this independently for red and blue. So, for example
green > A AND red < B AND blue < C AND green-red > D AND green-blue > E
Since one of your files is names "final lec final.vi", I'd stop here ;-)
Oh, and just for fun: Playing with brightness and contrast reveals the JPEG artifacts, which is one part of the problem:

Coreldraw Multiple Contours in VBA

Guys I Am trying to set up a three colour text that is editable
Basically what I want is the text to be black
A 1st contour of 1mm that is white
a 2nd contour of 2mm thick which is black
I have tried the following 2 step contour
ActiveSelection.CreateContour cdrContourOutside, 2, 2, , , CreateRGBColor(0, 0, 0), CreateRGBColor(255, 255, 255)
this works perfectly as I want and when I edit the text the contour changes to the new text however the contours are both the same width (2mm) and not 1 & 2mm as i want
Also I cant get it to specify the correct color for each contour
If I break apart the 1st contour then add another this gives me contours of different widths and colors but I then loose the edit ability as the contour is not attached to the text
Any Ideas I Know its possible as I have seen a commercial macro that does it
Any Help appreciated
Mark
The best I can do for you is to show you the object model. I do not have CorelDraw and therefore cannot test anything.
Here is the link to the CorelDraw Object Model.
http://apps.corel.com/partners_developers/csp/resources/CorelDRAW%20VBA%20Object%20Model.pdf
And here is a link to a Programming Guide for CorelDraw.
http://apps.corel.com/partners_developers/csp/resources/dvba_pg.pdf
You can look up "Applying Effects" on page 72 of the programming guide which may help.
I would suggest also looking at creating curves from the .Shapes object and then looking at the TextRange object. the TextRange.Text property is the actual text you want to see and the TextRange.colorindex is the color of the text I believe. You will have to do some exploring, but this should help.

Match labels to arrows in Excel flowchart using VBA

I'm writing a code generation tool using VBA in Excel (don't ask why—long story). I need to be able to "parse" a flowchart.
The problem is that Excel allows shapes to contain text, with the exception of connectors: lines and arrows can't contain text. To label an arrow, you just put a text box on top of it—but the box isn't "attached" to the arrow in a way that VBA can easily capture.
For example, a user might draw something like this:
Within my VBA code, I can use ActiveSheet.Shapes to find that the flowchart contains seven shapes: there are five boxes (the two labels are just boxes with no border) and two arrows. Then Shape.TextFrame2 will tell me what's written inside each box, and Shape.ConnectorFormat will tell me which box goes at the start and end of each arrow.
What I need is code that can deduce:
Label A belongs to the arrow from Box 1 to Box 2
Label B belongs to the arrow from Box 1 to Box 3
I can think of three ways of doing this, none of them satisfactory.
Ask the user to group each label with its corresponding arrow.
Find out the coordinates of the endpoints of each arrow, then
calculate which arrows pass through which labels.
Find out the coordinates of the corners of each box, then calculate
which labels lie between which pairs of boxes.
Method 1 makes things easier for the programmer but harder for the user. It opens up a lot of potential for user error. I don't see this as an acceptable solution.
Method 2 would be reasonably easy to implement, except that I don't know how to find out the coordinates!
Method 3 is doable (Shape.Left etc will give the coordinates) but computationally quite messy. It also has potential for ambiguity (depending on placement, the same label may be associated with more than one arrow).
Note that methods 2 and 3 both involve trying to match every label with every arrow: the complexity is quadratic. Typical applications will have 10–50 arrows, so this approach is feasible, if somewhat inelegant.
Does anyone have a better idea? Ideally it would be something that doesn't involve coordinate geometry and complicated logic, and doesn't involve asking users to change the way they draw flowcharts.
Edited to add: example 2 in response to Tim Williams
Here's a label whose bounding box intersects the bounding box of both arrows, and whose midpoint isn't inside the bounding box of either arrow. Visually it's easy for a human to see that it belongs with the left arrow, but programmatically it's hard to deal with. If I can find out the coordinates of the arrows' endpoints, then I can calculate that one arrow passes through the label's box but the other doesn't. But if all I have is the bounding rectangles of the arrows, then it doesn't work.
Interesting problem. What if you considered the range covered by the arrow and the range covered by the textbox and matched them up based on the most overlap.
Sub ListShapes()
Dim shp As Shape
Dim shpArrow As Shape
Dim vaArrows As Variant
Dim i As Long
Dim rIntersect As Range
Dim aBestFit() As String
Dim lMax As Long
vaArrows = Split("Straight Arrow Connector 7,Straight Arrow Connector 9", ",")
ReDim aBestFit(LBound(vaArrows) To UBound(vaArrows))
For i = LBound(vaArrows) To UBound(vaArrows)
Set shpArrow = Sheet1.Shapes(vaArrows(i))
lMax = 0
For Each shp In Sheet1.Shapes
If shp.Name Like "Label*" Then
Set rIntersect = Intersect(Sheet1.Range(shp.TopLeftCell, shp.BottomRightCell), _
Sheet1.Range(shpArrow.TopLeftCell, shpArrow.BottomRightCell))
If Not rIntersect Is Nothing Then
If rIntersect.Count > lMax Then
lMax = rIntersect.Count
aBestFit(i) = shp.Name
End If
End If
End If
Next shp
Next i
For i = LBound(vaArrows) To UBound(vaArrows)
Debug.Print vaArrows(i), aBestFit(i)
Next i
End Sub
I tested this with the five box-two arrow setup and nothing more complicated. I put my two arrows in an array, but I assume you have ways to identify the arrows. I also named my untethered boxes "Label x" so I could identify them, but again I assume you have something more sophisticated.
The code loops through every arrow. Inside that loop, it loops through every shape. If it's a label, then it counts the cells in the intersection of the two ranges. Whichever has the most is stored in the best fit array.
It would be nice if you had a reasonable corpus of flow charts to test this to see where the pitfalls are. I don't think this is necessarily better than use the coordinates, just a different approach.
You can find the coordinates of the arrow's endpoints as follows.
First of all, the .Left, .Top, .Width and .Height properties describe the bounding rectangle of the arrow, as Tim Williams points out.
Next, check the .HorizontalFlip and .VerticalFlip properties. If both are false, then the arrow runs from top left to bottom right in its bounding rectangle. That is, the beginning of the arrow has coordinates (.Left,.Top) and the end has coordinates (.Left+.Width,.Top+.Height).
If either *.Flip is true, then the coordinates need to be swapped around as appropriate. E.g., if .HorizontalFlip is true but .VerticalFlip false, then the arrow runs from (.Left+.Width,.Top) to (.Left,.Top+.Height).
As far as I can tell, this is not documented anywhere on MSDN. Thanks to Andy Pope for mentioning it at excelforums.com.
Given this, method 2 seems like the best approach.

dojox.charting: how to align the plotArea of 2 charts, one above another?

I'm trying to layout 2 linked charts, one above the other, similar to what you might see on the Google Finance page.
I can render both charts just fine, but getting the plotAreas to line up exactly is a bit of a mystery. The chart.plotArea.width of each chart seems to depend on the width of my Y axis labels. Thus the 2 charts are not the same width and have different values for chart.getCoord().l.
Right now, I'm using an offset which is manually calculated, but there must be a better way.
this.chart.render(); // top chart, getCoords().w=800
// manually set margins for lower chart to match
this.chartVol.margins.l = this.chart.offsets.l - 59 + 10;
this.chartVol.margins.r = this.chart.offsets.r - 31 + 10;
// render bottom chart
this.chartVol.render(); // bottom chart same width, getCoords().w=800
There are two simple ways to do it:
Use maxLabelSize and labelFunc. The former is the maximal label's size in pixels. The latter is a function, which takes a number, and returns a corresponding string label.
Use labels, which is an array of {value, text} objects, and include one long dummy string of desired size at the end with some bogus value.
I don't recall how to do it without custom labels, so if you feel like it is really needed, please submit an enhancement ticket.