Page 1 of 1

Exclude image Section At Processing Rate Topic: -----

#1 ricardosms  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 73
  • View blog
  • Posts: 301
  • Joined: 02-April 10

Posted 19 April 2011 - 08:56 AM

Hello, Fellow Programmers!

This is a greatly simplified version of a graphics processing program I am working on, but is set to show some concepts that were hard for me to grasp and that I had to research and in certain instances figure out by myself.

This program prepares a picture for processing using image attributes and a colormatrix,

        Dim TB3 As Single = TrackBar1.Value / 200

        Dim cm As ColorMatrix = New ColorMatrix(New Single()() _
         { _
          New Single() {TB3, 0, 0, 0.0, 0.0}, _
          New Single() {0, TB3, 0, 0.0, 0.0}, _
          New Single() {0, 0, TB3, 0.0, 0.0}, _
          New Single() {0, 0, 0, 1.0, 0.0}, _
          New Single() {0.01, 0.01, 0.01, 0.0, 1.0}})

.
.
.
            image_attr.SetColorMatrix(cm)
.




but not convolution filters to find edges (sharp changes on intensity or colors), and then replaces a section of it with a saved portion.


I process it with getpixel and setpixel methods, slow, but less complicated than Lockbits. I am not really excluding anything like the "isvisible" method for regions and paths.

There is a trackbar provided for variations on the colormatrix values; but I didn't include the variations on the color components as were set on my program.

The desktop has 4 picture boxes, one actual size, the others stretched, and one of them a shrunk image(picturebox3).
Picturebox1 has the original image and will show the resulting image, wich can be saved in sequence, sent to clipboard or printed.
Picturebox2 has a reduced view of the original.
Picturebox3 has a thumbnail modified image after aplying the image attributes and
Picturebox4 shows a preview resulting from processing the image on Picturebox3.

Here is a view:


Attached Image


The difference between "preview" and "border" that gives the final resuls is on the comparation of suroundind pixels, so it happens quicklier.

A checkbox allows you to select or not a region to exclude. Yo could also stop the process for larger pictures to view partial results.

OK!, Let's go to the code:

The first thing you do is to load an image to process, create the different images that will be needed and save some attributes of them:

    Private Sub OpenToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenToolStripMenuItem.Click
        Dim f As New OpenFileDialog
        Try
            With f
                .Filter = "Image Files|*.bmp;*.gif;*.jpg;*.png;*.tif"

                If .ShowDialog = DialogResult.OK Then
                    PictureBox1.Image = Image.FromFile(.FileName)
                    ' MessageBox.Show("Pixel format: " & PictureBox1.Image.PixelFormat.ToString())

                    PictureBox2.Image = Image.FromFile(.FileName)
                    PictureBox1.Tag = Image.FromFile(.FileName)
                    W = GetImageWidth(.FileName)
                    H = GetImageHeight(.FileName)
                    Ratio = CSng(W / H)
                    NewWidth = CInt(220 * Ratio)
                    NewHeight = 220
                    PictureBox2.Height = 220
                    PictureBox2.Width = NewWidth
                    PictureBox3.Height = 220
                    PictureBox3.Width = NewWidth
                    PictureBox4.Height = 220
                    PictureBox4.Width = NewWidth
                    PictureBox4.Visible = True
                    JustBefore()

                    PictureBox4.Image = Preview(ShrinkImage(PictureBox3.Image))
                    Try
                        selected_path.Reset()
                        gr_visible.Dispose()
                        gr_result.Dispose()
                        bm_result.Dispose()
                    Catch
                    End Try
                End If
            End With

        Catch ex As Exception
            MsgBox(ex.ToString)

        Finally
            If Not f Is Nothing Then
                f.Dispose()
                f = Nothing
            End If
        End Try

    End Sub



    Private Function GetImageHeight(ByRef file As String) As Integer
        Using image As System.Drawing.Image = System.Drawing.Image.FromFile(file)
            Return image.Height
        End Using
    End Function



    Private Function GetImageWidth(ByRef file As String) As Integer
        Using image As System.Drawing.Image = System.Drawing.Image.FromFile(file)
            Return image.Width
        End Using
    End Function



We have set the images on the pictureboxes and saved the dimensions of the original picture for future use.

The subroutine "JustBefore" sets the image attributes according to the colormatrix created and also produces a shunken image for picturebox3 calling the function shrinkimage:


    Private Sub JustBefore()
        Dim TB3 As Single = TrackBar1.Value / 200

        Dim cm As ColorMatrix = New ColorMatrix(New Single()() _
         { _
          New Single() {TB3, 0, 0, 0.0, 0.0}, _
          New Single() {0, TB3, 0, 0.0, 0.0}, _
          New Single() {0, 0, TB3, 0.0, 0.0}, _
          New Single() {0, 0, 0, 1.0, 0.0}, _
          New Single() {0.01, 0.01, 0.01, 0.0, 1.0}})


        Try
            Dim rect As Rectangle = Rectangle.Round(PictureBox2.Image.GetBounds(GraphicsUnit.Pixel))
            Dim wid As Integer = PictureBox2.Image.Width
            Dim hgt As Integer = PictureBox2.Image.Height
            Dim img As New Bitmap(wid, hgt)
            Dim gr As Graphics = Graphics.FromImage(img)

            image_attr.SetColorMatrix(cm) '0


            gr.DrawImage(PictureBox2.Image, rect, 0, 0, wid, hgt, GraphicsUnit.Pixel, image_attr)
            WorkImg = img
            PictureBox3.Image = ShrinkImage(img)
        Catch
        End Try
        PictureBox3.Refresh()
    End Sub



    Private Function ShrinkImage(ByVal from_pic As Image, Optional ByVal anti_alias As _
       Boolean = False) As Image
        ' Get the source Bitmap.
        Dim from_bm As New Bitmap(from_pic)

        ' Make the destination Bitmap.
        Dim wid As Integer = CInt(PictureBox1.Width * 220 / PictureBox1.Height) 'from_pic.Width / 2
        Dim hgt As Integer = 220 'from_pic.Height / 2
        Dim to_bm As New Bitmap(wid, hgt)

        ' Copy the image.
        Dim gr As Graphics = Graphics.FromImage(to_bm)
        If anti_alias Then gr.InterpolationMode = _
            Drawing2D.InterpolationMode.HighQualityBilinear
        gr.DrawImage(from_bm, 0, 0, wid - 1, hgt - 1)

        ' Display the result.
        ' to_pic.Image = to_bm
        gr.Dispose()
        Return to_bm
    End Function




The preview function shows you approximately how the image will come after processing the pixels. This will be on picturebox4

    Private Function Preview(ByVal Thumb As Image) As Image

        ' Dim bm As New Bitmap(PictureBox1.Image)
        Dim X As Integer
        Dim Y As Integer

        Dim Rx, Gx, Bx As Integer
        Dim Ry, Gy, By As Integer
        Dim Brig1, Brig2 As Integer

        Cursor = Cursors.WaitCursor

        Try
            Dim rect As Rectangle = Rectangle.Round(PictureBox4.Image.GetBounds(GraphicsUnit.Pixel))

            Dim pt As New Point(0, 0)
            Dim sz As New Size(NewWidth, 220)
            Dim rect1 As New Rectangle(pt, sz)
            Dim img As New Bitmap(NewWidth, 220)
            Dim gr As Graphics = Graphics.FromImage(img)

            gr.DrawImage(Thumb, rect1, 0, 0, NewWidth, 220, GraphicsUnit.Pixel)

            For X = 0 To img.Width - 2

                For Y = 0 To img.Height - 2
                    Rx = CInt(img.GetPixel(X, Y).R)
                    Gx = CInt(img.GetPixel(X, Y).G)
                    Bx = CInt(img.GetPixel(X, Y).B)/>
                    Brig1 = (Rx + Gx + Bx)
                    Ry = CInt(img.GetPixel(X + 1, Y).R)
                    Gy = CInt(img.GetPixel(X + 1, Y).G)
                    By = CInt(img.GetPixel(X + 1, Y).B)/>
                    Brig2 = (Ry + Gy + By)

                    If Math.Abs(2 * (Brig1 - Brig2)) > 20 Then
                        img.SetPixel(X, Y, Color.Black)
                    Else
                        img.SetPixel(X, Y, Color.White)
                    End If

                Next Y
                ' Application.DoEvents()
                Progress.Value = CInt((100 * X) / img.Width)
            Next X

            Progress.Value = 0
            Progress.Refresh()
            Cursor = Cursors.Default
            Return img

        Catch ex As Exception
            Cursor = Cursors.Default
            Progress.Value = 0
            Progress.Refresh()
            Return Thumb
        End Try
    End Function



You casn process the image and gt the results similar to the preview, but if you check the "Exclude Region" checkbox, you can click and drag on picturebox1 to create a graphics path and an enclosed region that will be saved when the mouseup event happens. Here are the MouseDown, MouseMove and MouseUp Handlers:

    Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        selected_path.Reset()
        If CheckBox1.Checked = True Then
            ' Erase any previous drawing.
            ' Save the starting point.
            m_MaxPoint = 0
            ReDim m_Points(m_MaxPoint)
            m_Points(m_MaxPoint).X = e.X
            m_Points(m_MaxPoint).Y = e.Y
        End If
    End Sub

    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        If CheckBox1.Checked = True And (e.Button = MouseButtons.Left) Then
            ' Do nothing if we're not selecting a region.
            If m_Points Is Nothing Then Exit Sub

            ' Save the new point.
            m_MaxPoint += 1
            ReDim Preserve m_Points(m_MaxPoint)
            m_Points(m_MaxPoint).X = e.X
            m_Points(m_MaxPoint).Y = e.Y

            ' Draw the latest line.
            Dim gr As Graphics = PictureBox1.CreateGraphics
            'gr.DrawLine(Pens.Yellow, _
            gr.DrawLine(Pens.White, _
                m_Points(m_MaxPoint).X, _
                m_Points(m_MaxPoint).Y, _
                m_Points(m_MaxPoint - 1).X, _
                m_Points(m_MaxPoint - 1).Y)
        End If
    End Sub

    Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
        If CheckBox1.Checked = True Then

            ' Do nothing if we're not selecting a region.
            If m_Points Is Nothing Then Exit Sub

            ' Close the region.
            If (m_Points(0).X <> m_Points(m_MaxPoint).X) Or _
               (m_Points(0).Y <> m_Points(m_MaxPoint).Y) _
            Then
                ' Save the new point.
                m_MaxPoint += 1
                ReDim Preserve m_Points(m_MaxPoint)
                m_Points(m_MaxPoint).X = m_Points(0).X
                m_Points(m_MaxPoint).Y = m_Points(0).Y
            End If

            ' Make the points into a Path.
            selected_path.AddLines(m_Points)

            ' Make the drawing permanent.
            Dim bm_visible As New Bitmap(PictureBox1.Image.Width, PictureBox1.Image.Height)
            'bm_visible = DirectCast(PictureBox1.Image.Clone, Bitmap)
            bm_visible = DirectCast(PictureBox1.Image, Bitmap)
            Try
                gr_visible = Graphics.FromImage(bm_visible)
                gr_visible.DrawPath(Pens.White, selected_path)
                PictureBox1.Image = bm_visible

                ' Copy the picture onto picResult,
                ' restricting it to the selected region.
                bm_result = DirectCast(PictureBox1.Image.Clone, Bitmap)
                gr_result = Graphics.FromImage(bm_result)
                gr_result.SetClip(selected_path, CombineMode.Exclude)
                ' We're no longer selecting a region.
                m_Points = Nothing
                GC.Collect()
            Catch
                MessageBox.Show("Can't Exclude Section: Pixel format: " & bm_visible.PixelFormat.ToString())
                m_Points = Nothing

                CheckBox1.Checked = False
                Exit Sub

            End Try

        End If
    End Sub



When you press "Process" , the image will be processed and then the saved region pasted on top of the resulting image.

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Border()
        If CheckBox1.Checked = True Then
            ' Create parallelogram for drawing image.
            Dim ulCorner As New Point(0, 0)
            Dim urCorner As New Point(PictureBox1.Width, 0)
            Dim llCorner As New Point(0, PictureBox1.Height)
            Dim destPara As Point() = {ulCorner, urCorner, llCorner}

            ' Create rectangle for source image.
            Dim srcRect As New Rectangle(0, 0, PictureBox1.Width, PictureBox1.Height)
            Dim units As GraphicsUnit = GraphicsUnit.Pixel
            Try
                ' Draw image to screen.
                gr_result.DrawImage(PictureBox1.Image, destPara, srcRect, units)
                PictureBox1.Image = bm_result
            Catch
                If bm_result IsNot Nothing Then bm_result.Dispose()
            End Try

        End If
        GC.Collect()
    End Sub




Attached Image Attached Image


The attachment contains the code, that also include the clipboard,save and print routines.

The save routine is a two part one, one for setting the name and the other to save the file:

    Private Sub SaveToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveToolStripMenuItem.Click
        Dim i As Integer
        Dim str As String
        For i = 1 To 1000
            If i < 10 Then str = "Picture_00" & i.ToString & ".jpg"
            If i > 9 And i < 100 Then str = "Picture_0" & i.ToString & ".jpg"
            If i > 99 Then str = "Picture_" & i.ToString & ".jpg"
            If i > 900 Then MsgBox("You Have Over 900 Pictures, Please Check And Delete Unnecesary Ones")
            If Not System.IO.File.Exists(str) Then
                Try
                    PictureBox1.Image.Save(str, System.Drawing.Imaging.ImageFormat.Jpeg) 'Cropped
                    'PictureBox1.Image.Save(str, System.Drawing.Imaging.ImageFormat.Png)
                Catch Ex As Exception
                    MsgBox("Could Not Write To Location")
                End Try
                Exit For
            End If
        Next
    End Sub



    Private Sub save()
        Dim i As Integer
        Dim str As String
        For i = 1 To 1000
            If i < 10 Then str = "Picture_00" & i.ToString & ".jpg"
            If i > 9 And i < 100 Then str = "Picture_0" & i.ToString & ".jpg"
            If i > 99 Then str = "Picture_" & i.ToString & ".jpg"
            If i > 900 Then MsgBox("You Have Over 900 Pictures, Please Check And Delete Unnecesary Ones")
            If Not System.IO.File.Exists(str) Then
                Try
                    PictureBox1.Image.Save(str, System.Drawing.Imaging.ImageFormat.Jpeg) 'Cropped
                    'PictureBox1.Image.Save(str, System.Drawing.Imaging.ImageFormat.Png)
                Catch Ex As Exception
                    MsgBox("Could Not Write To Location")
                End Try
                Exit For
            End If
        Next
    End Sub



Please comment.

Thank you

ricardosms

Attached File  Exclude image Section At Processing.zip (254.31K)
Number of downloads: 554

Is This A Good Question/Topic? 1
  • +

Replies To: Exclude image Section At Processing

#2 tarmizi_adam2005  Icon User is offline

  • جوروترا

Reputation: 228
  • View blog
  • Posts: 817
  • Joined: 18-April 09

Posted 05 August 2011 - 01:26 AM

This is interesting !
Was This Post Helpful? 0
  • +
  • -

#3 ricardosms  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 73
  • View blog
  • Posts: 301
  • Joined: 02-April 10

Posted 05 August 2011 - 03:32 AM

Hello tarmizi_adam2005

It is. I am just playing with ideas I have, but this may be useful for some people.

Also, if you use lockbits instead of getpixel and setpixel for the main image, you really improve speed. Also you could convert it to sepia or grayscale with a colormatrix and it will happen almost inmediately.

regards,

ricardosms
Was This Post Helpful? 0
  • +
  • -

#4 ricardosms  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 73
  • View blog
  • Posts: 301
  • Joined: 02-April 10

Posted 11 August 2011 - 05:56 AM

Hello:

As I said at the beginning, this is a greatly simplified version of a program I am working on. My actual program is much more complicated and with lots of options more. Instead of one colormatrix I have 43 of them, some with complex mathematical equations to change the balance of the colors, using trackbars and numeric up-downs.

Here is a view of the desktop:


Attached Image


I can get a fairly good edge detection without utilizing convolution, depending on the image. Some with texture, too much detail on the background or that have been resized before, don't come too good, that's why I am still experimenting. I have few routines to clean afterwards, some of them work on 24 bits, other do better on 32 bits, so I switch between modes. And I have other nice effects, that I am trying to perfect.

My process generally goes this way:

1. Load
2. Enlarge to get a cleaner image and narrower edges.
3. Choose one of the color matrices depending on general appearance and Apply it.
4. Make an initial test on the intermediate work image.
4. Depending on the result. Adjust Intensity and color variation tolerance.
3. Use a cleaning routine on the resulting image.

The general process is to compare pixels for intensity variation and fine tuning by variation on the shade of colors, then change pixels to black or white depending on results of the comparison.

Here is a 'printscreen' of some examples, they have not been manually edited. Larger images are inside the attached zip:


Attached Image


This program is not intended to go to the market like a comercial program; it is for my private use, but if some people is interested on the code, I think I have enough material for another tutorial.

If you look a this image of the desktop, you will see that there are a lot of buttons, options and adjustments; also there are some on the menu. The same process with a different option or adjustment can give lots of different results to choose from. One of them, changing to shadow directions can give 12 different results. Some of them work better on diagonals, other are preferably to get thicker edges. All depends on the picture and your taste.

Drop me a line and I will see what I can do.

ricardosms.

This post has been edited by ricardosms: 12 August 2011 - 10:11 AM

Was This Post Helpful? 0
  • +
  • -

#5 bnvelarde  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 20-April 12

Posted 10 May 2012 - 02:00 AM

you're so great! :) i admire you
Was This Post Helpful? 0
  • +
  • -

#6 ricardosms  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 73
  • View blog
  • Posts: 301
  • Joined: 02-April 10

Posted 10 May 2012 - 01:41 PM

Gracias.

BTW Welcome to DIC.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1