|
is there supposed to be something in the gui for INITDOMAINS?
|
|
|
|
|
You might want to add that somewhere in your text so people can find it easier.
Good work, by the way.
|
|
|
|
|
Hello, could you please post here a link to an article about the luminance segmentation? In the intro you wrote, that it's easily "Googleable", but I'm so dum , that I can't find anything useful. I'm playing around with OpenCV and I'm trying to make my own cartoonizer just for fun and this luminance thing seems to be very useful and I would like to know more about it in general (not reverse engineer your code ).
Thanks man, I would really appreciate it. Have a nice day
|
|
|
|
|
how to remove border style in the result of cartoonizer....thanks ron
|
|
|
|
|
Hi Ron,
me again.
Topic 1
=======
The performance of the code: In the main procedure zEFF_BilateralFilter, non RGB Part, I see 5 nested loops. Ok, this is the algorithmen, using gausina, predifed data etc.
But: The array COMPUTEsingle contains values of type single, this values are later used to access the array Fast_ExpIntensity, here i can see implicit type converts from single to integer. Have you examid the influece of converting single to integer?
I don't know anything about the performace of converting single to integer in .NET.
Topic 2
=======
The code COMPUTEsingle(2, X, Y) is executed twice in the inner loop of the 4 nested loops. Isn't it better to do this once before the third loop starts? Or is this done by compileroptimacation features? Do you have any information about implicit .NET compiler optimizations?
We/You/I should check this .....
Added: Topic1, Topic2, doesn't realy help ....., the 5 loops (with removed logic in the inner loop) are slow .....
regards,
bauer
modified on Monday, April 18, 2011 7:42 AM
|
|
|
|
|
I actually have a CUDA version of this.
NVidia released a bilateral filter in their CUDA SDK.
It is a command line executable that takes a BMP file and outputs a PPM file.
I make a crude wrapper (Image save as BMP ---> send to EXE ---> load resulting PPM file ---> Apply Countour ---> Return Bitmap).
It can do 20 passes of bilateral filtering in a few seconds.
I will be releasing an article in the next month or so for a Movie Cartoonizer (1 hour per minute at 30 fps for 720p resolution).
I would like to use Interop to keep the bitmap bytes in memory and pass them to the C++ DLL and get back the processed byte array, but I have not had much success. I could really use somebody who is talented in C++ Interop with .NET.
|
|
|
|
|
Hi Ron,
yes, it makes sense to transfer the algorithm to C, C++ and check, if it's faster. My attempts to improve the performance with the .NET coding where not very successful. No idea, what happens inside the compiled .NET coding. The problem seems not to be the typeconverts from single to integer accessing the arrays, the loops in general are are little bit slow using large images or a large number of iterations.
But on the other hand: Handling a picture with resolution 3000 * 4000 with radius = 5 and iterations 4 are a lot of operations to be done.
To transfer data from .NET to C++ (and back) is in general no problem, should work. I did it with strings and integers in some database projects. It should work as well with other datatypes, like single's, double etc. and datastructures like arrays.
regards,
bauer
|
|
|
|
|
GPU acceleration is the only way to make a bilateral filter faster.
When I release the CUDA version, you will a big difference in the performance time.
You just need an Nvidia Chipset with driver that supports CUDA.
|
|
|
|
|
Hi Ron,
if I'm processing a image with Image.Width mod 8 <> 0 the program produces pretty poor results, for example image width 400 works pretty good, image width 433 doesn't work.
The problem is in the image helper class, procedure GetBitmapBits.
Converting the 1 dimensioanl byte array to the 3 dimensional byte array (the 3 nested loops) doesn't work in this way, if width of image mod 8 <> 0, because in this situation the m_BitmapData = m_Bitmap.LockBits(bounds, _
Imaging.ImageLockMode.ReadWrite, _
m_Bitmap.PixelFormat) code returns with padding bytes for each line in the bitmap. The resulting m_BitmapData array contains Stride * Image.Heigth bytes and NOT Width * Height * 3 Bytes.
See stride property of the bitmap data class.
This happens using the net 2.0 framework, Windows XP.
regards,
bauer
modified on Friday, April 15, 2011 3:30 PM
|
|
|
|
|
Thanks for finding that bug.
I'll fix the code in the next few days.
|
|
|
|
|
Hi Ron,
have a look to the following class. This is part of code, I use for my own graphic routines. This class may replace your ImageHelper class to fix the problem.
Thank you for your post and the job for converting the VB 6.0 Coding.
regards,
bauer
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Drawing.Imaging
''' <summary>
''' Provides fast access to a bitmap
''' </summary>
''' <remarks></remarks>
Public Class FastBitmapAccess
' ======================================================================================================================================================
' Interfaces
' ======================================================================================================================================================
Implements IDisposable
' ======================================================================================================================================================
' DataAreas
' ======================================================================================================================================================
''' <summary>
''' The Bytes of the bitmap
''' Dimension 0 : RGB Color of the Pixel
''' Dimension 1 : x axsis
''' Dimension 2 : y axsis
''' </summary>
''' <remarks></remarks>
Private _BytesMatrix As Byte(,,)
''' <summary>
''' Referece to the bitmap
''' </summary>
''' <remarks></remarks>
Private _bm As Bitmap
' ======================================================================================================================================================
' Constructors / Destructors
' ======================================================================================================================================================
#Region "Constructors"
''' <summary>
''' Constructor
''' </summary>
''' <param name="pBM"></param>
''' <remarks></remarks>
Public Sub New(ByVal pBM As Bitmap)
Me._bm = pBM
Me.GetBytesFromBitmap()
End Sub
#End Region
#Region "Desctructor"
Private disposedValue As Boolean = False ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: free managed resources when explicitly called
Me.PutBytesToBitmap()
End If
' TODO: free shared unmanaged resources
End If
Me.disposedValue = True
End Sub
#Region " IDisposable Support "
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
#End Region
' ======================================================================================================================================================
' Support routines
' ======================================================================================================================================================
#Region "Support routines"
''' <summary>
''' Copys bitmap bytes to local BitmapBytesMatrix
''' </summary>
''' <remarks></remarks>
Private Sub GetBytesFromBitmap()
Dim l_StartIndexForLine As Integer
Dim l_StartIndexNextPixel As Integer
Dim l_BytesVector() As Byte
Dim l_BitmapData As BitmapData
Dim l_BytesPerLine As Integer
Dim l_BytesTotal As Integer
Dim l_ByteDepth As Integer
l_ByteDepth = Image.GetPixelFormatSize(_bm.PixelFormat) \ 8
If l_ByteDepth = 3 Then
l_BitmapData = Me._bm.LockBits(New Rectangle(0, 0, Me._bm.Width, Me._bm.Height), Imaging.ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb)
l_BytesPerLine = l_BitmapData.Stride
l_BytesTotal = l_BytesPerLine * l_BitmapData.Height
ReDim l_BytesVector(l_BytesTotal - 1)
ReDim Me._BytesMatrix(l_ByteDepth - 1, Me._bm.Width - 1, Me._bm.Height - 1)
Marshal.Copy(l_BitmapData.Scan0, l_BytesVector, 0, l_BytesTotal)
For y As Integer = 0 To Me._bm.Height - 1
l_StartIndexNextPixel = l_StartIndexForLine
For x As Integer = 0 To Me._bm.Width - 1
Me._BytesMatrix(0, x, y) = l_BytesVector(l_StartIndexNextPixel)
l_StartIndexNextPixel = l_StartIndexNextPixel + 1
Me._BytesMatrix(1, x, y) = l_BytesVector(l_StartIndexNextPixel)
l_StartIndexNextPixel = l_StartIndexNextPixel + 1
Me._BytesMatrix(2, x, y) = l_BytesVector(l_StartIndexNextPixel)
l_StartIndexNextPixel = l_StartIndexNextPixel + 1
Next
l_StartIndexForLine = l_StartIndexForLine + l_BytesPerLine
Next
Me._bm.UnlockBits(l_BitmapData)
Else
Throw New Exception("ByteDepth not supported")
End If
End Sub
''' <summary>
''' Copies local BitmapBytesMatrix back to original bitmap
''' </summary>
''' <remarks></remarks>
Private Sub PutBytesToBitmap()
Dim l_StartIndexForLine As Integer
Dim l_StartIndexNextPixel As Integer
Dim l_BytesVector() As Byte
Dim l_BitmapData As BitmapData
Dim l_BytesPerLine As Integer
Dim l_BytesTotal As Integer
Dim l_byteDepth As Integer
l_byteDepth = Image.GetPixelFormatSize(Me._bm.PixelFormat) \ 8
If l_byteDepth = 3 Then
l_BitmapData = _bm.LockBits(New Rectangle(0, 0, Me._bm.Width, Me._bm.Height), Imaging.ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb)
l_BytesPerLine = l_BitmapData.Stride
l_BytesTotal = l_BytesPerLine * l_BitmapData.Height
ReDim l_BytesVector(l_BytesTotal - 1)
For y As Integer = 0 To Me._bm.Height - 1
l_StartIndexNextPixel = l_StartIndexForLine
For x As Integer = 0 To Me._bm.Width - 1
l_BytesVector(l_StartIndexNextPixel) = Me._BytesMatrix(0, x, y)
l_StartIndexNextPixel = l_StartIndexNextPixel + 1
l_BytesVector(l_StartIndexNextPixel) = Me._BytesMatrix(1, x, y)
l_StartIndexNextPixel = l_StartIndexNextPixel + 1
l_BytesVector(l_StartIndexNextPixel) = Me._BytesMatrix(2, x, y)
l_StartIndexNextPixel = l_StartIndexNextPixel + 1
Next
l_StartIndexForLine = l_StartIndexForLine + l_BytesPerLine
Next
Marshal.Copy(l_BytesVector, 0, l_BitmapData.Scan0, l_BytesTotal)
Me._bm.UnlockBits(l_BitmapData)
ReDim Me._BytesMatrix(-1, -1, -1)
Else
Throw New Exception("ByteDepth not supported")
End If
End Sub
#End Region
' ======================================================================================================================================================
' Public Propertys / Methods
' ======================================================================================================================================================
#Region "Propertys / Methods"
''' <summary>
''' Gets Color of a pixel
''' </summary>
''' <param name="x"></param>
''' <param name="y"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function GetPixel(ByVal x As Integer, ByVal y As Integer) As Color
Return Color.FromArgb(0, Me._BytesMatrix(2, x, y), Me._BytesMatrix(1, x, y), Me._BytesMatrix(0, x, y))
End Function
''' <summary>
''' Sets color of a pixel
''' </summary>
''' <param name="x"></param>
''' <param name="y"></param>
''' <param name="Color"></param>
''' <remarks></remarks>
Public Sub SetPixel(ByVal x As Integer, ByVal y As Integer, ByVal Color As Color)
Me._BytesMatrix(0, x, y) = Color.B
Me._BytesMatrix(1, x, y) = Color.G
Me._BytesMatrix(2, x, y) = Color.R
End Sub
''' <summary>
''' Matrix ob Bytes per Pixel
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property BytesMatrix() As Byte(,,)
Get
Return Me._BytesMatrix
End Get
End Property
#End Region
End Class
|
|
|
|
|
I have added your code to the repository and the zip archive in this article should be updated in the next day or two.
Thanks for the fix.
I tried multiple times to track down the cause of the "pseudo scanline interlace effect" that was occurring on certain images. I just never thought to look at the bitmap byte access code.
|
|
|
|
|
Hi Ron,
your update by adding my code snippet works, I just downloaded it, tested it, perfect.
regards,
bauer
|
|
|
|
|
|
Nice post Ron
|
|
|
|
|