Plotting sampling graph on VB.NET - vb.net

I am collecting data from an Arduino and transmit on Visual Basic through the serial port. Now I wanted to plot a graph with time vs electrical energy (unit kWh) - time along the x-axis and electrical energy along the y-axis. Usually I am getting data of the current from Arduino.
Now I wanted to learn how to start plotting the graph. I need a simple example explaining plotting a graph for sample. I tried some example code. It seems they are not working.
How do I plot a graph time vs current read from serial? Once Visual Basic starts running, it should save data w.r.t system time and date.
Example available here
Current code
Imports System
Imports System.IO.Ports
Imports System.ComponentModel
Imports System.Threading
Imports System.Drawing
Public Class Form1
Dim myPort As Array
Dim Distance As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
myPort = IO.Ports.SerialPort.GetPortNames()
PortComboBox.Items.AddRange(myPort)
BaudComboBox.Items.Add(9600)
BaudComboBox.Items.Add(19200)
BaudComboBox.Items.Add(38400)
BaudComboBox.Items.Add(57600)
BaudComboBox.Items.Add(115200)
ConnectButton.Enabled = True
DisconnectButton.Enabled = False
End Sub
Private Sub ConnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConnectButton.Click
SerialPort1.PortName = PortComboBox.Text
SerialPort1.BaudRate = BaudComboBox.Text
SerialPort1.Open()
Timer1.Start()
'lblMessage.Text = PortComboBox.Text & " Connected."
ConnectButton.Enabled = False
DisconnectButton.Enabled = True
End Sub
Private Sub DisconnectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DisconnectButton.Click
SerialPort1.Close()
DisconnectButton.Enabled = False
ConnectButton.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Try
SerialPort1.Write("c")
System.Threading.Thread.Sleep(250)
Dim k As Double
Dim distance As String = SerialPort1.ReadLine()
k = CDbl(distance)
ListBoxSensor.Text = k
Catch ex As Exception
End Try
End Sub
Private Sub Relay_ON_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Relay_ON.Click
SerialPort1.Write("1")
End Sub
Private Sub Relay_Off_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Relay_Off.Click
SerialPort1.Write("0")
End Sub
End Class

Add a picturebox, a timer a button and a textbox:
PictureBox1 size = 768, 279
timer interval to 500
Private img As Bitmap
Private imgClone As Bitmap
Private widthInterval As Integer
'the distance from the left side of picturebox where x axis starts
Private leftPad As Integer = 50
'the distance from the down side of picturebox where x axis is
Private downPad As Integer = 30
'the distance from the up side of picturebox where y axis ends
Private upPad As Integer = 50
'the distance from the right side of picturebox where x axis ends
Private rightPad As Integer = 80
Private rn As New Random
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
drawBack()
Timer1.Enabled = True
End Sub
Private Sub drawBack()
Static count As Boolean = False
Dim g As Graphics
'number of values in x axis e.g 1, 2, 3, ... representing time
Dim numX As Integer = 23
'number of values in y axis representing KW/h
Dim numY As Integer = 5
Dim stringFormat As New StringFormat()
'arreys to hold the text for both axies
Dim arrayTextX(numX), arrayTextY(numY - 1) As String
Dim i As Integer
'the distance from the right side of picturebox where x axis stops
Dim rightPad As Integer = 80
Dim brush As Brush = New SolidBrush(Color.FromArgb(245, 255, 255))
Dim pen As Pen = New Pen(Color.FromArgb(212, 212, 212), 1)
Dim height, x, y As Integer
'Run once
If count = True Then
Return
End If
count = True
stringFormat.Alignment = StringAlignment.Center
img = New Bitmap(PictureBox1.Width, PictureBox1.Height)
imgClone = New Bitmap(PictureBox1.Width, PictureBox1.Height)
g = Graphics.FromImage(img)
g.SmoothingMode = SmoothingMode.AntiAlias
g.Clear(Color.White)
'the distance in x axis between each value
widthInterval = CInt((PictureBox1.Width - leftPad - rightPad) / (numX + 1))
'the distance in y axis between each value
height = CInt((PictureBox1.Height - upPad - downPad) / (numY + 1))
'fill arrays with text
For i = 0 To numX - 1
arrayTextX(i) = (i + 1).ToString
Next
For i = 0 To numY - 1
arrayTextY(i) = ((i + 1) * height).ToString
Next
'fill background of graph with color
g.FillRectangle(brush, New Rectangle(leftPad, upPad, PictureBox1.Width - leftPad - rightPad + 1, _
PictureBox1.Height - downPad - upPad))
'vertical lines
x = leftPad
For i = 0 To numX - 1
x += widthInterval
g.DrawLine(pen, x, PictureBox1.Height - downPad, x, upPad)
g.DrawString(arrayTextX(i), New Font("Arial", 8), Brushes.Black, _
New Rectangle(x - 10, PictureBox1.Height - downPad + 3, 20, 20), stringFormat)
Next
'horizontal lines
stringFormat.Alignment = StringAlignment.Far
y = PictureBox1.Height - downPad
For i = 0 To numY - 1
y -= height
g.DrawLine(pen, leftPad, y, PictureBox1.Width - rightPad, y)
g.DrawString(arrayTextY(i), New Font("Arial", 8), Brushes.Black, _
New Rectangle(0, y - 6, leftPad - 5, 20), stringFormat)
Next
g.DrawString("KW/Hour", New Font("Arial", 8, FontStyle.Bold), Brushes.Black, _
New PointF(5, 5))
g.DrawString("Time", New Font("Arial", 8, FontStyle.Bold), Brushes.Black, _
New PointF(PictureBox1.Width - 50, PictureBox1.Height - 20))
'draws x axis
g.DrawLine(Pens.Black, New Point(leftPad, PictureBox1.Height - downPad), _
New Point(PictureBox1.Width - rightPad, PictureBox1.Height - downPad))
'draws y axis
g.DrawLine(Pens.Black, New Point(leftPad, PictureBox1.Height - downPad), _
New Point(leftPad, upPad))
g.Dispose()
PictureBox1.Image = img
imgClone = CType(img.Clone, Bitmap)
End Sub
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
Dim value, x As Integer
Dim g As Graphics
Dim pntEnd As Point
Static pnt As Point = New Point(-1, -1)
Static staticX As Integer = -1
Dim hour As Integer = DateTime.Now.Hour
Dim minute As Integer = DateTime.Now.Minute
Dim second As Integer = DateTime.Now.Second
second = minute * 60 + second
x = leftPad + hour * widthInterval + CInt(CDbl(widthInterval - 1) * CDbl(second) / 3600.0R)
If pnt.X >= 0 Then
'checks if the new points x coordinate is the same as the previous and returns
If x <= staticX Then
Return
End If
End If
GetValue(value)
pntEnd = New Point(x, PictureBox1.Height - value - downPad)
g = Graphics.FromImage(img)
g.SmoothingMode = SmoothingMode.AntiAlias
If pnt.X < 0 Then
g.DrawLine(Pens.Red, pntEnd, pntEnd)
Else
g.DrawLine(Pens.Red, pnt, pntEnd)
End If
g.Dispose()
pnt = pntEnd
staticX = x
PictureBox1.Invalidate()
End Sub
Private Sub GetValue(ByRef value As Integer)
'here you can take the value from arduino.
value = rn.Next(0, PictureBox1.Height - downPad - upPad) 'random value
End Sub
When you press Button1 the graph starts.
Calculate width of graph (x axis)
width = PictureBox1.Width - leftPad - rightPad
this width is equivelant with 24h or 86400sec. So you should set the timer interval to
Timer1.Interval = CInt((86400 / width ) * 1000) 'in milliseconds
There is no need to be that because the tick function checks if the
new point is the same as the previous. So set timer interval to 1 second.

Related

Timer won't start in vb.net

I have started the timer with Game.Start() and by using a breakpoint I have determined that the timer is enabled, the interval is 100. However when stepping through my code, the timer sub is ignored and the paint sub is given priority. Therefore, the timer is never being run.
Here is the code which i am referring to :
Public Class Form1
Dim speed_s As Integer = 5
Dim speed_w As Integer = 5
Dim speed_d As Integer = 5
Dim speed_a As Integer = 5
Dim Enemy1 As New computerControlled(1, 1, Me)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
player1.Bounds = New Rectangle(player1.Location.X, player1.Location.Y, player1.Width, player1.Height)
'Enemy1.DrawEnemy(Me)
Game.Enabled = True
Game.Start()
End Sub
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.W Then
player1.Top -= speed_w
ElseIf e.KeyCode = Keys.S Then
player1.Top += speed_s
ElseIf e.KeyCode = Keys.A Then
player1.Left -= speed_a
ElseIf e.KeyCode = Keys.D Then
player1.Left += speed_d
' Enemy1.enemypic.Left += 10 this moves enemy class well
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Game.Tick
'Enemy1.enemypic.Left += 10
Enemy1.Walk()
MsgBox("hi")
End Sub
Private MOUSE_X As Integer
Private MOUSE_Y As Integer
Private Sub Form1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
MOUSE_X = e.X
MOUSE_Y = e.Y
End Sub
Private Sub Player_Paint(sender As Object, e As PaintEventArgs) Handles player1.Paint
Dim GFX As Graphics = e.Graphics
Dim BMP As Bitmap = Image.FromFile("c:\firaas\ball.png")
Dim center As Point = New Point(player1.Width \ 2, player1.Height \ 2)
Dim angle As Integer
Dim rad As Double
Dim CENTRE_X As Integer
Dim CENTRE_Y As Integer
'=========================
Using cyan As New Pen(Brushes.Cyan, 2)
GFX.ResetTransform()
GFX.TranslateTransform(CENTRE_X, CENTRE_Y)
GFX.RotateTransform(angle) ' angle in DEGREES!
'For Each pos As PointF In pat.Positions
' Dim r As New Rectangle(pos.X, pos.Y, 1, 1)
' r.Inflate(3, 3)
' GFX.DrawEllipse(cyan, r)
' Next
End Using
'===========================
Dim rotatematrix As New System.Drawing.Drawing2D.Matrix()
Dim srcRect As New RectangleF(64, 64, 64, 64)
Dim OffsetX As Single = Me.Width / 2 - player1.Width / 2
Dim OffsetY As Single = Me.Height / 2 - player1.Height / 2
CENTRE_X = player1.Location.X + player1.Width / 2
CENTRE_Y = player1.Location.Y + player1.Height / 2
rad = Math.Atan2(MOUSE_Y - CENTRE_Y, MOUSE_X - CENTRE_X)
angle = rad * (180 / Math.PI)
'================================================================================
BMP = New Bitmap(My.Resources.ball)
GFX.TranslateTransform(player1.Height / 2, player1.Width / 2)
GFX.RotateTransform(angle)
GFX.DrawImage(BMP, 64, 64, player1.Location.X, player1.Location.Y)
GFX.ResetTransform()
e.Graphics.TranslateTransform(player1.Height / 2, player1.Width / 2)
e.Graphics.RotateTransform(angle)
' BMP.RotateAt(angle, New PointF(player1.Location.X, player1.Location.Y))
e.Graphics.DrawImage(BMP, New Point(-player1.Width \ 2, -player1.Height \ 2))
e.Graphics.DrawImageUnscaled(BMP, New Point(0, 0))
player1.Invalidate()
End Sub
End Class
'latest project
If this is the complete code, it doesn't seem like you're setting your timer's interval.
So you're telling it, it can tick and what to do each tick but not actually setting a time for it to tick.
Game.Interval = 60000 '1 minute
Game.Enabled = True
Game.Start() 'I don't believe you need this line

How to print three different rectangles in picturebox side by side vb.net

i have three different buttons in a form which have three different widths and heights of a rectangle.each time the button is clicked , the width and height is loaded and eachtime picturebox is clicked rectangle is created on a picturebox.i want the three rectangles to go side by side in X axis but wheneven i click the first rectangle and click on picturebox, three same rectangle is drawn. i want some help with the loop. here is my code.
Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
Dim myGraphics As Graphics = PictureBox1.CreateGraphics()
Dim myPen As Pen
myPen = New Pen(Drawing.Color.Black, 1)
myGraphics.DrawLine(myPen, pt1.X, pt1.Y, pt2.X, pt2.Y)
myGraphics.DrawLine(myPen, pt3.X, pt3.Y, pt4.X, pt4.Y)
End Sub
Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles PictureBox1.Click 'MessageBox.Show(e.Clicks)
Dim myGraphics As Graphics = PictureBox1.CreateGraphics
midpoint.X = (pt1.X + pt2.X) / 2
midpoint.Y = (pt3.Y + pt4.Y) / 2
Dim l(2) As Point
l(0).X = midpoint.X
l(0).Y = midpoint.Y
If e.X >= midpoint.X Then
Dim i As Integer
For i = 0 To 2
If (i > 0) Then
l(i).X += l(i - 1).X + myRect.Width
l(i).Y = midpoint.Y - myRect.Height
Dim myPen As Pen
myPen = New Pen(Drawing.Color.Black, 1)
myGraphics.DrawRectangle(myPen, l(i).X, l(i).Y, myRect.Width, myRect.Height)
Else
l(i).X = midpoint.X
l(i).Y = midpoint.Y - myRect.Height
Dim myPen As Pen
myPen = New Pen(Drawing.Color.Black, 1)
myGraphics.DrawRectangle(myPen, l(i).X, l(i).Y, myRect.Width, myRect.Height)
End If
Next
End If
Here's an example of what jmcilhinney is talking about:
Public Class Form1
' these represent the x-axis?
Private pt1 As New Point(0, 100)
Private pt2 As New Point(200, 100)
' these represent the y-axis?
Private pt3 As New Point(100, 0)
Private pt4 As New Point(100, 200)
' represents the size of the box to draw
Private myRect As New Size(30, 20)
Private numClicks As Integer
Private rects As New List(Of Rectangle)
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
' draw the x and y axis
e.Graphics.DrawLine(Pens.Black, pt1, pt2)
e.Graphics.DrawLine(Pens.Black, pt3, pt4)
' draw all the rectangles in our list
For Each rc As Rectangle In rects
e.Graphics.DrawRectangle(Pens.Blue, rc)
Next
End Sub
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
Dim origin As New Point((pt1.X + pt2.X) / 2, (pt3.Y + pt4.Y) / 2)
Dim clickedPt As Point = PictureBox1.PointToClient(Cursor.Position)
If clickedPt.X > origin.X Then
If numClicks < 3 Then
Dim rc As New Rectangle(New Point(origin.X + (numClicks * myRect.Width), origin.Y - myRect.Height), myRect)
rects.Add(rc)
numClicks = numClicks + 1
PictureBox1.Invalidate()
End If
End If
End Sub
End Class

Zoom to mouse position after Graphics transform, in VB.Net

How to zoom to the cursor position after the graphics component has been transformed?
I want to be able to zoom to any of the test rectangles.
The panning is done with the Middle mouse button.
MouseWheel Event handles the zooming.
Ignore the DrawGrid method, it's just to get some visual reference.
Public Class Diagram
Dim renderOrigin As New Point
Dim zoom As Single = 1.0F
Dim startPoint As New Point
Dim isDragging As Boolean = False
Dim gridSpacing As Integer = 50
Dim testRects() As Rectangle = New Rectangle() {New Rectangle(-150, -150, 70, 25), _
New Rectangle(-10, -5, 70, 25), _
New Rectangle(100, 8, 70, 25), _
New Rectangle(300, 80, 70, 25)}
Sub New()
SetStyle(ControlStyles.ResizeRedraw, True)
SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
SetStyle(ControlStyles.AllPaintingInWmPaint, True)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
Protected Overrides Sub OnPaint(e As PaintEventArgs)
Dim g As Graphics = e.Graphics
g.TranslateTransform(renderOrigin.X, renderOrigin.Y)
g.ScaleTransform(zoom, zoom)
drawGrid(g)
g.FillRectangles(Brushes.Green, testRects.ToArray)
End Sub
Private Sub drawGrid(ByRef g As Graphics)
If zoom < 0.6 Then
Exit Sub
End If
Dim oX As Integer = renderOrigin.X
Dim oY As Integer = renderOrigin.Y
Dim maxStepX As Integer = Math.Ceiling((Width - oX) / gridSpacing) / zoom
Dim maxStepY As Integer = Math.Ceiling((Height - oY) / gridSpacing) / zoom
Dim minStepX As Integer = Math.Floor((oX * -1) / gridSpacing) / zoom
Dim minStepY As Integer = Math.Floor((oY * -1) / gridSpacing) / zoom
For x = minStepX To maxStepX
For y = minStepY To maxStepY
g.DrawLine(Pens.Black, x * gridSpacing, gridSpacing * y, (x + 1) * gridSpacing, gridSpacing * y)
g.DrawLine(Pens.Black, x * gridSpacing, gridSpacing * y, x * gridSpacing, (y + 1) * gridSpacing)
Next
Next
End Sub
Private Sub Diagram_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
If e.Button = Windows.Forms.MouseButtons.Middle Then
startPoint = New Point(e.X - renderOrigin.X, e.Y - renderOrigin.Y)
isDragging = True
End If
End Sub
Private Sub Diagram_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
If isDragging Then
renderOrigin = New Point(e.X - startPoint.X, e.Y - startPoint.Y)
Invalidate()
End If
End Sub
Private Sub Diagram_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
isDragging = False
End Sub
Private Sub Diagram_MouseWheel(sender As Object, e As MouseEventArgs) Handles Me.MouseWheel
Dim i As Single = (e.Delta / Math.Abs(e.Delta)) / 100
zoom += i
If zoom < 0.1 Then zoom = 0.1
If zoom > 1.0 Then zoom = 1.0
renderOrigin = New Point(e.X - e.X * zoom, e.Y - e.Y * zoom)
Invalidate()
End Sub
End Class
1st. thing to know is what your mouse location is in control coordinates. It is part of the EventArguments in the scroll event. Save that location to a field.
2nd is you have to apply a TranslateTransform with the negativ saved location to move the zoom location to 0/0 then apply the ScaleTransform.
3rd move the picture back to it's original location by another TranslateTransform. now with the saved mouse location (not negated).
Thomas

A Graphics object cannot be created from an image that has an indexed pixel format

I have a program that when you click on picturebox1, it transfers the image inside it to picturebox2. Then I have an interpolation code to modify it to a nearestneighbor pixel rendering. It also draws a pixel grid on picturebox2 to line up around the pixels. I have picturebox2 set to stretch image. I tried 2 different methods of drawing on the picturebox2. I am having a problem converting the image back to the right size to transfer it back to picturebox1 after its been edited with the paintbrush.
CODE:
Imports System.Windows.Forms
Imports System.Drawing
Imports System
Imports System.IO
Public Class Form1
Dim Brush = Brushes.Black
Dim COLOR1 As Color
Dim BMP As Bitmap
Dim Draw As Boolean
CODE: when you click on the picturebox1(topleft) it transfers its image to picturebox2(canvaseditor) does the grid draw, interpolate mode etc.
Private Sub topleft_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles topleft.Click
tiledcanvas.BackgroundImage = topleft.Image
Label1.Text = "Top-Left"
'CANVAS PIXEL GRID CODE
If topleft.Image Is Nothing Then
Else
canvaseditor.Image = Nothing
canvaseditor.Image = topleft.Image
canvaseditor.Width = topleft.Width * 8 + 1
canvaseditor.Height = topleft.Height * 8 + 1
'load and draw the image(s) once
BackgroundImage1 = New Bitmap(topleft.Image)
bmpNew = New Bitmap(canvaseditor.Width * scaleFactor, canvaseditor.Height * scaleFactor)
Using g As Graphics = Graphics.FromImage(bmpNew)
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half
g.DrawImage(BackgroundImage1, 0, 0, bmpNew.Width, bmpNew.Height)
End Using
canvaseditor.Focus()
GroupBox13.Focus()
End If
End Sub
CODE: the paintbrush code, the mousedown, mousemove, and mouseup events on picturebox2(canvaseditor)
Private Sub canvaseditor_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles canvaseditor.MouseMove
If Draw = True Then
PaintBrush(e.X, e.Y)
Else
End If
'If down = True Then
'canvaseditor.CreateGraphics.FillRectangle(Brush, e.X, e.Y, 8, 8)
'End If
' LocalMousePosition = canvaseditor.PointToClient(Cursor.Position)
'Dim X As Integer
'Dim Y As Integer
'If LocalMousePosition.X > 0 And LocalMousePosition.X < 9 Then
'X = 1
' ElseIf LocalMousePosition.X > 8 And LocalMousePosition.X < 17 Then
'X = 2
'ElseIf LocalMousePosition.X > 16 And LocalMousePosition.X < 25 Then
'X = 3
'End If
'Label6.Text = (X & ", " & Y)
End Sub
Private Sub PaintBrush(ByVal X As Integer, ByVal Y As Integer)
Using g As Graphics = Graphics.FromImage(canvaseditor.Image)
g.FillRectangle(New SolidBrush(Color.Black), New Rectangle(X, Y, 6, 6))
End Using
canvaseditor.Refresh()
End Sub
Private Sub canvaseditor_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles canvaseditor.MouseDown
'down = True
'If down = True Then
'Dim NEWBMP As New Bitmap(topleft.Width, topleft.Height)
'Dim graph As Graphics = Graphics.FromImage(NEWBMP)
' graph.FillRectangle(Brush, e.X, e.Y, 8, 8)
'topleft.Image = NEWBMP
'End If
'down = True
'If down = True Then
'canvaseditor.CreateGraphics.FillRectangle(Brush, e.X, e.Y, 8, 8)
'End If
Draw = True
PaintBrush(e.X, e.Y)
End Sub
Private Sub canvaseditor_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles canvaseditor.MouseUp
Draw = False
End Sub
and heres the first paint sub i made:
Private Sub canvaseditor_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles canvaseditor.Paint
If Not bmpNew Is Nothing Then
e.Graphics.DrawImage(bmpNew, 0, 0)
End If
Dim g As Graphics = e.Graphics
Dim pn As New Pen(Color.DimGray) '~~~ color of the lines
Dim x As Integer
Dim y As Integer
Dim intSpacing As Integer = 8 '~~~ spacing between adjacent lines
'~~~ Draw the horizontal lines
x = canvaseditor.Width
For y = 0 To canvaseditor.Height Step intSpacing
g.DrawLine(pn, New Point(0, y), New Point(x, y))
Next
'~~~ Draw the vertical lines
y = canvaseditor.Height
For x = 0 To canvaseditor.Width Step intSpacing
g.DrawLine(pn, New Point(x, 0), New Point(x, y))
Next
End Sub
hoping this is understandable so someone can point me in the right direction. thanks.

Obtained incorrect standard deviation and mean values with moving rectangle in VB2010

I have an grayscale image, I have been a able to display a rectangle on the image to extract the ROI and compute the standard deviation and mean. However, when I'm moving the rectangle around, i notice I have the wrong values for the image, especially where the image is entirely black. At this area, i should be getting a zero for the mean and standard deviation. However, im obtaining a 0 for the mean and negative values for the standard deviation and other point of this black area the mean increases to the mean the same as light dominated areas. I have been struggling to come up with a solution. Are there any ideas to help. I'll be grateful. My code for the mousemove button and mean and standard deviation are posted below. Thanks.
Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
Dim mean As Double = 0
Dim meancount As Integer = 0
Dim bmap As New Bitmap(400, 400)
bmap = PictureBox1.Image
Dim colorpixel As Color = bmap.GetPixel(e.X, e.Y)
' Dim pixels As Double = colorpixel.R + colorpixel.G + colorpixel.B
If e.Button = Windows.Forms.MouseButtons.Left AndAlso Rect.Contains(e.Location) Then
If (PictureBox1.Image Is Nothing) Or (PictureBox1.Height - (e.Y + SquareHeight) < 0) Or (PictureBox1.Width - (e.X + SquareWidth) < 0) Then
Else
Dim ROI As New Bitmap(400, 400)
Dim x As Integer = 0
Dim countx As Integer = 0
Dim county As Integer = 0
For i = e.X To (e.X + SquareWidth)
For j = (e.Y + x) To (e.Y + SquareHeight)
Dim pixelcolor As Color = bmap.GetPixel(i, j)
ROI.SetPixel(countx, county, pixelcolor)
mean = mean + pixelcolor.R + pixelcolor.G + pixelcolor.B
county += 1
meancount += 1
Next
county = 0
countx += 1
x = x + 1
Next
mean = mean / meancount
Dim SD = mean - 75
Dim area As Integer = (SquareHeight * SquareWidth)
Dim anotherForm As Form2
anotherForm = New Form2(mean, SD, area, 34)
anotherForm.Show()
End If
End If
' Catch ex As Exception
' MessageBox.Show(ex.Message())
' End Try
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
Rect.X = e.X + x
Rect.Y = e.Y + y
Rect.Width = SquareWidth
Rect.Height = SquareHeight
' Label1.Text = "XRect: " + Rect.X.ToString() + " YRect: " + Rect.Y.ToString() + " Xmouse " + e.X.ToString() + " Ymouse " + e.Y.ToString()
PictureBox1.Refresh()
End Sub
Private Sub PictureBox1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
e.Graphics.DrawRectangle(Pens.Red, Rect)
End Sub
Private Function StandardDeviation(ByVal image As Bitmap, ByVal mean As Double, ByVal meancount As Integer) As Double
Dim SD(SquareHeight * SquareWidth) As Double
Dim count As Integer = 0
For i = 0 To SquareWidth
For j = 0 To SquareHeight
Dim pixelcolor As Color = image.GetPixel(i, j)
SD(count) = Double.Parse(pixelcolor.R) + Double.Parse(pixelcolor.G) + Double.Parse(pixelcolor.B) - mean
count += 1
Next
Next
Dim SDsum As Double = 0
For i = 0 To count
SDsum = SDsum + SD(i)
Next
SDsum = SDsum / (SquareHeight * SquareWidth)
SDsum = ((SDsum) ^ (1 / 2))
Return SDsum
End Function
Private Sub PictureBox1_MouseClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseClick
Dim P As Point = e.Location
P = New Point
End Sub
You should calc mean like
mean = mean / (meancount * 3) (there is 3 colors added) and it is better to calc running mean instead of summing all and divide later. I guess there can be more math errors.