How can I detect a strong change in color on an image so that I can mark it as an edge? For example a red ball on a blue background, I need to find the edges of the ball.
Thanks.
Thanks.
Graphics 640,480,32,2 SetBuffer BackBuffer() Type fill_pointT Field x%,y% End Type Global result_h#, result_s#, result_l# Global thresh = 30 Global total_r,total_g,total_b,total_points image = LoadImage("ball_seg.jpg") Global image_width = ImageWidth(image) Global image_height = ImageHeight(image) new_image = CreateImage(image_width,image_height) ; Image pixel RGB and HSL matrices. Dim pix_rgb(image_width-1,image_height-1,2) Dim pix_hsl(image_width-1,image_height-1,2) IB_image = ImageBuffer(image) LockBuffer IB_image For y = 0 To image_height-1 For x = 0 To image_width-1 pix = ReadPixelFast(x,y,IB_image) r = (pix And $00FF0000) Shr 16 g = (pix And $0000FF00) Shr 8 b = (pix And $000000FF) pix_rgb(x,y,0) = r pix_rgb(x,y,1) = g pix_rgb(x,y,2) = b rgb_to_hsl(r,g,b) pix_hsl(x,y,0) = result_h pix_hsl(x,y,1) = result_s pix_hsl(x,y,2) = result_l Next Next UnlockBuffer IB_image IB_new_image = ImageBuffer(new_image) For y = 0 To image_height-1 Print y For x = 0 To image_width-1 Dim pix_fill(image_width-1,image_height-1) fill(x,y) mean_r = Float(total_r) / total_points mean_g = Float(total_g) / total_points mean_b = Float(total_b) / total_points rgb = $FF000000 Or (mean_r Shl 16) Or (mean_g Shl 8) Or mean_b LockBuffer IB_new_image For yy = 0 To image_height-1 For xx = 0 To image_width-1 If pix_fill(xx,yy) WritePixelFast xx,yy,rgb,IB_new_image EndIf Next Next UnlockBuffer IB_new_image Next Next Cls DrawBlock image,0,0 DrawBlock new_image,image_width+19,0 Flip WaitKey() End Function match(h%, s%, l%, x%, y%) dh = Abs(h - pix_hsl(x,y,0)) If (dh <= thresh) Or ((200-dh) <= thresh) ds = Abs(s - pix_hsl(x,y,1)) If (ds <= thresh) Or ((200-ds) <= thresh) dl = Abs(l - pix_hsl(x,y,2)) If (dl <= thresh) Or ((200-dl) <= thresh) Return True EndIf EndIf EndIf End Function Function fill(x%, y%) p.fill_pointT = New fill_pointT p\x = x p\y = y base_h = pix_hsl(x,y,0) base_s = pix_hsl(x,y,1) base_l = pix_hsl(x,y,2) total_points = 0 total_r = 0 total_g = 0 total_b = 0 While p <> Null point_x = p\x point_y = p\y If match(base_h,base_s,base_l,point_x,point_y) And pix_fill(point_x,point_y) = 0 ; Find left-most pixel on this line to start filling from. While point_x > 0 If match(base_h,base_s,base_l,point_x-1,point_y) And pix_fill(point_x-1,point_y) = 0 point_x = point_x - 1 Else Exit EndIf Wend add_above = True add_below = True ; Start filling pixels from start point, moving rightwards... Repeat ; Add pixel above to fill queue if neccessary. If point_y > 0 If match(base_h,base_s,base_l,point_x,point_y-1) And pix_fill(point_x,point_y-1) = 0 If add_above add_above = False new_p.fill_pointT = New fill_pointT new_p\x = point_x new_p\y = point_y - 1 EndIf Else add_above = True EndIf EndIf ; Add pixel below to fill queue if neccessary. If point_y < image_height-1 If match(base_h,base_s,base_l,point_x,point_y+1) And pix_fill(point_x,point_y+1) = 0 If add_below add_below = False new_p.fill_pointT = New fill_pointT new_p\x = point_x new_p\y = point_y + 1 EndIf Else add_below = True EndIf EndIf ; Fill pixel and move on to next if it's fillable. pix_fill(point_x,point_y) = 1 total_r = total_r + pix_rgb(point_x,point_y,0) total_g = total_g + pix_rgb(point_x,point_y,1) total_b = total_b + pix_rgb(point_x,point_y,2) total_points = total_points + 1 point_x = point_x + 1 If point_x >= image_width Then Exit If (Not match(base_h,base_s,base_l,point_x,point_y)) Then Exit Forever EndIf ; Remove the processed fill point from the queue. Delete p p.fill_pointT = First fill_pointT Wend End Function ; ; ; Function rgb_to_hsl(ir%, ig%, ib%) ; Scale RGB down to unit range (0-1). r# = ir/255.0 g# = ig/255.0 b# = ib/255.0 If r > g max_is = 0 max_color# = r min_color# = g Else max_is = 1 max_color# = g min_color# = r EndIf If b > max_color max_is = 2 max_color = b ElseIf b < min_color min_color = b EndIf ; Luminance. result_l = (max_color + min_color) / 2.0 If max_color = min_color ; Color is grey. result_s = 0 ;result_h = 0 Else delta# = (max_color - min_color) ; Saturation. If result_l < 0.5 result_s = delta / (max_color + min_color) Else result_s = delta / (2.0 - max_color - min_color) EndIf ; Hue. Select max_is Case 0 ; Red. result_h = (g - b) / delta Case 1 ; Green. result_h = 2.0 + (b - r) / delta Case 2 ; Blue. result_h = 4.0 + (r - g) / delta End Select result_h = result_h * 60.0 If result_h < 0 Then result_h = result_h + 360.0 EndIf ; Scale back to CP_HSL_SCALE range. result_h = ((result_h/360.0) * 200) result_s = (result_s * 200) result_l = (result_l * 200) End Function