Image buffer reading/writing

Hello to everybody,
I need to get (put) the image buffer for external manipulation.
How can I read/write all the image / ROI /  single pixel from the active image?
Thank you
Regards
Maurizio

Best Answer

  • edited December 2013 Accepted Answer
    Hi Maurizio,

    IQL has special class McRegionAccess for reading and writing pixel data, it has  GetArea, GetLine, GetPixel to read data and corresponding Put functions for writing data back.
    Here is the example of using GetArea to invert a monochrome 8-bit image:
        Public Sub PixelOperationsTest()
            Dim im As McImage=ThisApplication.ActiveImage
            If im Is Nothing Then Exit Sub
            If im.NumberOfChannels>1 OrElse im.BitsPerChannel>8 Then Exit Sub'support only 8-bit mone image
            'create region access for whole image of monochrome 8-bit image (e.g. Spots.tif)
            Dim ra As McRegionAccess=im.CreateRegionAccess()
            ra.RegionMask=im.Aoi'process only active ROI
            Dim data(,) As Byte
            'get 2D array of pixel data
            ra.GetArea(data)
            For i As Integer=0 To data.GetUpperBound(0)
                For j As Integer=0 To data.GetUpperBound(1)
                    'invert
                    data(i,j)=255-data(i,j)
                Next
            Next
            'put data back
            ra.PutArea(data)
        End Sub
    
    and example of using GetArea to invert a color 8-bit image:

    You can find additional info on McRegionAccess  page of Automation help.
        Public Sub PixelOperationsTestColor()
            Dim im As McImage=ThisApplication.ActiveImage
            If im Is Nothing Then Exit Sub
            If im.NumberOfChannels=1 OrElse im.BitsPerChannel>8 Then Exit Sub'support only 8-bit color image
            'create region access for whole image of color 8-bit image
            Dim ra As McRegionAccess=im.CreateRegionAccess()
            ra.RegionMask=im.Aoi'process only active ROI
            Dim data(,,) As Byte
            'get 3D array of pixel data
            ra.GetArea(data)
            For c As Integer=0 To data.GetUpperBound(0)
                For i As Integer=0 To data.GetUpperBound(1)
                    For j As Integer=0 To data.GetUpperBound(2)
                        'invert
                        data(c,i,j)=255-data(c,i,j)
                    Next
                Next
            Next
            'put data back
            ra.PutArea(data)
        End Sub
    
    Regards,

    Yuri
     

Answers

  • I am looking to do pixel level manipulation similar to above except I am working with 12-bit mono 2D image (and maybe 16-bit mono in future). When I do not define "data" variable above (does not like it when I define as Byte), GetArea properly grabs data as Object type. I then try to take the average of 2 pixel intensities and apply it to a nearby pixel as shown below.

    data(i,j) = ( data(i-1,j) + data(i+1,j) ) / 2

    The math works. However, when it tries to assign to data(i,j), result I get is an error "source type is not primitive". If I convert result to string, I get error "object cannot be stored in array of this type"

    Can anyone help

    Thanks
  • Data from 12 or 16-bit images are in Int16 type, so you have to convert it to proper type before assignment, like this

    data(i,j)= CType(( data(i-1,j) + data(i+1,j) ) / 2,System.Int16)

    Here is the complete macro:

         Public Sub PixelOperationsTest()
            Dim im As McImage=ThisApplication.ActiveImage
            If im Is Nothing Then Exit Sub
            If im.NumberOfChannels>1 OrElse im.BitsPerChannel<12 OrElse im.BitsPerChannel>16  Then Exit Sub'support only 12 or 16-bit images
            'create region access for whole image of monochrome image
            Dim ra As McRegionAccess=im.CreateRegionAccess()
            ra.RegionMask=im.Aoi'process only active ROI
            Dim data(,) As Object
            'get 2D array of pixel data
            ra.GetArea(data)
            For i As Integer=1 To data.GetUpperBound(0)-1
                For j As Integer=0 To data.GetUpperBound(1)
                    'invert
                    data(i,j)= CType(( data(i-1,j) + data(i+1,j) ) / 2,System.Int16)
                Next
            Next
            'put data back
            ra.PutArea(data)
        End Sub
    


    Yuri 
  • Thanks Yuri

    That worked perfectly.
  • Hi Yuri,
    when working on the data() structure by using your code
    Dim ra As McRegionAccess=im.CreateRegionAccess()
    ra.RegionMask=im.Aoi
    Dim data(,) As Object
    ra.GetArea(data)
     I always get the whole image in my data-matrix, but I just want to get a special Region.
    How do I have to select a region to get the data-matrix?

    Thx,
    Svenja
  • edited January 29
    The Region mask is used only for PutArea operation, so to get only ROI pixels the Region Access must have bounds, Check the sample macro here http://forums.mediacy.com/discussion/874/getting-access-to-pixel-data-of-a-special-region 

    Yuri

Sign In or Register to comment.