Home Image-Pro Plus Automation with Macros

Modifying color Images to help with segmentation

(Originally posted by Earl Sanford on 1/11/2008)

I am having some difficulty in putting together a basic macro that looks at each pixel in an TIF image to determine what color it should be called. All of the examples I have found looking through the help screens and online deal with grayscale images. Hopefully one of you can help me figure out how to modify a color image.
What I want to do is compare the red, green and blue components of a pixel and change the value of these components so I will have an image that is easier to segment - basically a four color image. Below I have attached a portion of the macro I have been working on. The images I am running this on are 1280 x 1024 TIF images.

If anyone can figure out what I am doing wrong, or has a better idea as to how to segment color images that vary widely in color range, I would greatly appreciate hearing from you.

Sub Modify_TIF()

Dim I As Integer
Dim j As Integer
Dim Red_Pixel As Integer
Dim Green_Pixel As Integer
Dim Blue_Pixel As Integer
Dim ImBufByte As Byte
Dim Reg As RECT


ReDim ImBuf(Reg.Left To Reg.Right,Reg.top To Reg.bottom) As Integer

For j = 1 To 3072
For I = 1 To 3840

Red_Pixel=ImBuf(I, j)
Green_Pixel=ImBuf(I+1, j)
Blue_Pixel=ImBuf(I+2, j)

If Blue_Pixel > Red_Pixel Then
ImBuf(I, j)=100
ImBuf(I+1, j)=100
ImBuf(I+2, j)=245
GoTo next_pixel
End If
If Red_Pixel > Blue_Pixel Then
If Green_Pixel > Blue_Pixel Then
ImBuf(I, j)=200
ImBuf(I+1, j)=160
ImBuf(I+2, j)=100
GoTo next_pixel
End If
ImBuf(I, j)=200
ImBuf(I+1, j)=100
ImBuf(I+2, j)=160
GoTo next_pixel
End If

'If pixel not red, yellow or blue - make it "black"
ImBuf(I, j)=10
ImBuf(I+1, j)=10
ImBuf(I+2, j)=10

Next I
Next j


' refresh the display of the active document.

ret = IpAppUpdateDoc(DOCSEL_ACTIVE)

End Sub


  • Options

    (Originally posted by YuriG on 1/11/2008)

    The ranges on the IpDocGetArea & IpDocPutArea are hard to get right. The dimensions should look like:

    ReDim ImBuf(Reg.Left*3 To (Reg.Right*3+2),Reg.top To Reg.bottom) As Integer

    The width needs be multiplied by a factor of 3, because it needs 3 numbers for each pixel. Of course, this changes the range of your for loops, too:

    For j = Reg.top To Reg.bottom
    For I = Reg.Left*3 To (Reg.Right)*3 Step 3

    The "Step 3" makes sure that "I" increments by 3 on every loop.
    Finally, since the "Next" command causes the I & j variables to be incremented, so you don't need the I=I+3 & j=j+3.

    A way to avoid accessing the individual pixel data would be to:
    - Use the Process | Color Channel command to extract each color
    - Use Process | Operations to mathematically subtract each of the colors from each other
    - Use Process | Segmentation to "mask" any values > 0
    - Use the segmentation window to "Create Preview Image",
    . . . using the "Class Color on Black" color option
    . . . changing the "Class Color" (by clicking on the color square right next to the [New] and [Del] buttons)
    - Adding all of the created "Preview" images together
    This can work, BUT it's a lot more steps than just directly access the pixel data, like you're doing in your code. Also, it uses a lot more memory, since it opens up a bunch of copies of the image.


  • Options
    edited June 2013

    (Originally posted by KevinR on 1/14/2008)

    I would endorse following the previous suggestion - Extract the color channels and perform whatever math you wish on those.

    It will use more memory, but a few copies of 1280x1024 images doesn't add up to much, and image operation commands will be _much_ faster than macro based pixel operations. Operations such as MIN and MAX, multiplying an image by 255 to turn it into a mask (any non-zero value becomes 255, zero values remain zero), and fairly simple combinations should give you your results.


Sign In or Register to comment.