Seam carving
Übersicht

![]() |
FirstdeathmakerBetreff: Seam carving |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi, und schon wieder mal was von mir. Diesmal zum Thema seam carving:
www.seamcarving.com Meine funktion macht genau das, ist dabei nur leider nicht so schnell wie in dem Video. Man kann damit aber wunderbar herumspielen. Code starten, image wählen dass man verkleinert haben möchte und zuschauen wie das Programm arbeitet.... (tipp: nicht im debugmodus starten, dadurch wird es um einiges langsamer) Code: [AUSKLAPPEN] Rem
Seam-carving implementation by Christian Geißler for the blitzbasic community 19.6.2008 End Rem SuperStrict Graphics 800 , 600 , 0 SetBlend alphablend Local image:TImage = LoadImage(RequestFile$( "Select picture","Image Files:png,jpg,bmp;All Files:*")) If image = Null End Local width:Int = 50 'how many x - pixels do you want to remove? Local height:int = 50 'how many y - pixels do you want to remove? Local pic:TPixmap = SeamCarving(LockImage(image) , ImageWidth(image)-width , ImageHeight(image)-height ,5, 4)'<Pixmap>, newwidth, newheight, resolution (1=best), showdemoflags: 1=show difference, 2=show flow, 4=show removing Local savepath:String = RequestFile$( "Save picture" , "png file:png; jpg file:jpg",True) If Lower(ExtractExt(savepath))="png" SavePixmapPNG(pic , savepath ) Else SavePixmapJPeg(pic , savepath) EndIf Print "saving successfully" Repeat Cls DrawPixmap pic , 0 , 0 DrawText "Press esc to end",10,10 Flip Until KeyHit(KEY_ESCAPE) End Rem bbdoc: Scales TPixmap through seam-carving algorithm to lower size param map - TPixmap you want to scale param newWidth, newHeight - new (lower) size in pixels you want the image to be param resolution - steps until new flow will be calculated. Speeds up the function, but if you have enought time use '1' to get best result. param demomode - 1=show difference, 2=show flow, 4=show removing End Rem Function SeamCarving:TPixmap(map:TPixmap, newWidth:Int , newHeight:Int, resolution:Int = 10, demomode:Byte) Local mapwidth:Int = PixmapWidth(map) Local mapheight:Int = PixmapHeight(map) Local pixel:Byte[mapwidth , mapheight,4] Local distarray:Long[mapwidth , mapheight] Local patharray:Int[mapwidth , mapheight] Local widthDist:Int = mapwidth - newWidth Local heightDist:Int = mapheight - newHeight Local pathh:Int[] Local pathv:Int[] Local maxdist:Int Local drawtmpimages:Byte = demomode 'flags: 1=difference, 2=flow, 4=removing Local x:Int = 0 Local y:Int = 0 'Imagepixelwerte in array �bertragen For y:Int = 0 Until mapheight For x:Int = 0 Until mapwidth Local color:Int = ReadPixel(map , x , y) 'DebugLog "color: "+Hex(color) pixel[x , y , 0] = color Shr 24 pixel[x , y , 1] = color Shr 16 pixel[x , y , 2] = color Shr 8 pixel[x , y, 3] = color Next Next 'Horizontal Local steps:Int = 0 While mapheight > newHeight If drawtmpimages = 0 DrawText "horizontal step: " + (steps + 1) , 10 , 10 Flip 0 EndIf If Steps Mod resolution = 0 'Pixeldistanzwerte errechnen For y:Int = 0 Until mapheight x:Int = 0 distarray[x , y] = Sqr( (pixel[x + 1 , y , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x + 1 , y , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x + 1 , y , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x + 1 , y , 3] - pixel[x , y , 3]) ^ 2) * 2 x = mapwidth-1 distarray[x , y] = Sqr((pixel[x - 1 , y , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x - 1 , y , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x - 1 , y , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x - 1 , y , 3] - pixel[x , y , 3]) ^ 2) * 2 For x:Int = 1 Until mapwidth - 1 Local dist1:Long = Sqr((pixel[x - 1 , y , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x - 1 , y , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x - 1 , y , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x - 1 , y , 3] - pixel[x , y , 3]) ^ 2) Local dist2:Long = Sqr((pixel[x + 1 , y , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x + 1 , y , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x + 1 , y , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x + 1 , y , 3] - pixel[x , y , 3]) ^ 2) distarray[x , y] = dist1 + dist2 Next Next 'TEST For x:Int = 0 Until mapwidth y:Int = 0 distarray[x , y]:+Sqr((pixel[x, y+1 , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x, y+1 , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x, y+1 , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x, y+1 , 3] - pixel[x , y , 3]) ^ 2) * 2 y = mapheight - 1 distarray[x , y]:+Sqr((pixel[x, y-1 , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x, y-1 , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x, y-1 , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x, y-1 , 3] - pixel[x , y , 3]) ^ 2) * 2 For y:Int = 1 Until mapheight - 1 Local dist1:Long = Sqr((pixel[x, y-1 , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x, y-1 , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x, y-1 , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x, y-1 , 3] - pixel[x , y , 3]) ^ 2) Local dist2:Long = Sqr((pixel[x, y+1 , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x, y+1 , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x, y+1 , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x, y+1 , 3] - pixel[x , y , 3]) ^ 2) distarray[x , y]:+ dist1 + dist2 Next Next 'TEST ENDE If drawtmpimages & 1 map = ResizePixmap(map ,mapwidth , mapheight) For y:Int = 0 Until mapheight For x:Int = 0 Until mapwidth WritePixel(map,x,y,((distarray[x,y]*255)/(8*255))*$10101 + $FF000000) 'shows difference Next Next Cls DrawPixmap map , 0 , 0 DrawText "Horizontal step: " + (steps + 1),10,10 Flip 0 EndIf 'Horizontal Pfade berechnen patharray = New Int[mapwidth , mapheight] For x:Int = 1 Until mapwidth For y:Int = 0 Until mapheight Local s:Int = 0 Local toggle:Int = ((x Mod 2)*2-1) If y > ((x+1) Mod 2) * (mapheight-1) If distarray[x - 1 , y - toggle] + patharray[x - 1 , y - toggle] < distarray[x - 1 , y + s] + patharray[x - s , y + s] s = - toggle EndIf If y <((x) Mod 2) * (mapheight-1) If distarray[x - 1 , y + toggle] + patharray[x - 1 , y + toggle] < distarray[x - 1 , y - s] + patharray[x - 1 , y - s] s = + toggle EndIf patharray[x , y] = distarray[x - 1 , y + s] + patharray[x - 1 , y + s] maxdist = Max(maxdist,patharray[x,y]) Next Next If drawtmpimages & 2 map = ResizePixmap(map ,mapwidth , mapheight) For y:Int = 0 Until mapheight For x:Int = 0 Until mapwidth WritePixel(map,x,y,((patharray[x,y]*255)/(maxdist))*$10101 + $FF000000) 'shows flow 'If pathh[x] = y WritePixel(map,x,y,$FFFF0000) Next Next Cls DrawPixmap map , 0 , 0 DrawText "Horizontal step: " + (steps + 1),10,10 Flip 0 EndIf EndIf 'looking for best horizontal path to delete (lowest cost) 'find startplace pathh = New Int[mapwidth] Local currentmin:Int = $7FFFFFFF For y:Int = 0 Until mapheight If patharray[mapwidth - 1 , y] < currentmin currentmin = patharray[mapwidth - 1 , y] pathh[mapwidth - 1] = y EndIf Next 'find way through flow For x:Int = mapwidth - 2 To 0 Step - 1 Local oldy:Int = pathh[x + 1] Local s:Int = 0 If oldy > 0 If patharray[x , oldy - 1] < patharray[x , oldy + s] s = - 1 If oldy < mapheight - 1 If patharray[x , oldy + 1] < patharray[x , oldy + s] s = 1 pathh[x] = oldy + s Next If drawtmpimages & 4 map = ResizePixmap(map ,mapwidth , mapheight) For y:Int = 0 Until mapheight For x:Int = 0 Until mapwidth WritePixel(map,x,y,pixel[x,y,0]*$1000000 + pixel[x,y,1]*$10000 + pixel[x,y,2]*$100 + pixel[x,y,3]) ' shows picture 'WritePixel(map,x,y,((patharray[x,y]*255)/(maxdist))*$10101 + $FF000000) 'shows flow If pathh[x] = y WritePixel(map,x,y,$FFFF0000) 'WritePixel(map,x,y,((distarray[x,y]*255)/(8*255))*$10101 + $FF000000) 'shows difference Next Next Cls DrawPixmap map , 0 , 0 DrawText "Horizontal step: " + (steps + 1),10,10 Flip 0 EndIf 'Delete row from all arrays Local oldpixel:Byte[ , , ] = pixel Local olddistarray:Long[ , ] = distarray Local oldpatharray:Int[ , ] = patharray pixel = New Byte[mapwidth , mapheight - 1,pixel.Dimensions()[2]] distarray = New Long[mapwidth , mapheight - 1] patharray = New Int[mapwidth, mapheight-1] For x:Int = 0 Until mapwidth y = 0 For Local yc:Int = 0 Until mapheight If pathh[x] <> yc pixel[x , y , 0] = oldpixel[x , yc , 0] pixel[x , y , 1] = oldpixel[x , yc , 1] pixel[x , y , 2] = oldpixel[x , yc , 2] pixel[x , y , 3] = oldpixel[x , yc , 3] distarray[x , y] = olddistarray[x , yc] patharray[x,y] = oldpatharray[x,yc] y:+ 1 EndIf Next Next mapheight:- 1 steps:+1 Wend steps=0 While mapwidth > newWidth If drawtmpimages = 0 DrawText "vertical step: " + (steps + 1) , 10 , 10 Flip 0 EndIf If Steps Mod resolution = 0 'Vertikal Pixeldistanzwerte errechnen For x:Int = 0 Until mapwidth y:Int = 0 distarray[x , y] = Sqr((pixel[x, y+1 , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x, y+1 , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x, y+1 , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x, y+1 , 3] - pixel[x , y , 3]) ^ 2) * 2 y = mapheight - 1 distarray[x , y] = Sqr((pixel[x, y-1 , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x, y-1 , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x, y-1 , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x, y-1 , 3] - pixel[x , y , 3]) ^ 2) * 2 For y:Int = 1 Until mapheight - 1 Local dist1:Long = Sqr((pixel[x, y-1 , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x, y-1 , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x, y-1 , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x, y-1 , 3] - pixel[x , y , 3]) ^ 2) Local dist2:Long = Sqr((pixel[x, y+1 , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x, y+1 , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x, y+1 , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x, y+1 , 3] - pixel[x , y , 3]) ^ 2) distarray[x , y]= dist1 + dist2 Next Next 'TEST For y:Int = 0 Until mapheight x:Int = 0 distarray[x , y]:+Sqr( (pixel[x + 1 , y , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x + 1 , y , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x + 1 , y , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x + 1 , y , 3] - pixel[x , y , 3]) ^ 2) * 2 x = mapwidth-1 distarray[x , y]:+Sqr((pixel[x - 1 , y , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x - 1 , y , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x - 1 , y , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x - 1 , y , 3] - pixel[x , y , 3]) ^ 2) * 2 For x:Int = 1 Until mapwidth - 1 Local dist1:Long = Sqr((pixel[x - 1 , y , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x - 1 , y , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x - 1 , y , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x - 1 , y , 3] - pixel[x , y , 3]) ^ 2) Local dist2:Long = Sqr((pixel[x + 1 , y , 0] - pixel[x , y , 0]) ^ 2 + (pixel[x + 1 , y , 1] - pixel[x , y , 1]) ^ 2 + (pixel[x + 1 , y , 2] - pixel[x , y , 2]) ^ 2 + (pixel[x + 1 , y , 3] - pixel[x , y , 3]) ^ 2) distarray[x , y]:+dist1 + dist2 Next Next 'TEST END If drawtmpimages & 1 map = ResizePixmap(map ,mapwidth , mapheight) For y:Int = 0 Until mapheight For x:Int = 0 Until mapwidth WritePixel(map,x,y,((distarray[x,y]*255)/(8*255))*$10101 + $FF000000) 'shows difference Next Next Cls DrawPixmap map , 0 , 0 DrawText "Vertikal step: " + (steps + 1),10,10 Flip 0 EndIf 'Vertikal Pfade berechnen Local maxdist:Int patharray = New Int[mapwidth , mapheight] For y:Int = 1 Until mapheight For x:Int = 0 Until mapwidth Local s:Int = 0 Local toggle:Int = ((y Mod 2)*2-1) If x > ((y+1) Mod 2) * (mapwidth-1) If distarray[x - toggle , y - 1] + patharray[x - toggle , y - 1] < distarray[x + s , y - 1] + patharray[x + s , y - 1] s = - toggle EndIf If x <((y) Mod 2) * (mapwidth-1) If distarray[x + toggle , y - 1] + patharray[x + toggle , y - 1] < distarray[x + s , y - 1] + patharray[x + s , y - 1] s = toggle EndIf patharray[x , y] = distarray[x + s , y - 1] + patharray[x + s , y - 1] maxdist = Max(maxdist,patharray[x,y]) Next Next If drawtmpimages & 2 map = ResizePixmap(map ,mapwidth , mapheight) For y:Int = 0 Until mapheight For x:Int = 0 Until mapwidth WritePixel(map,x,y,((patharray[x,y]*255)/(maxdist))*$10101 + $FF000000) 'shows flow Next Next Cls DrawPixmap map , 0 , 0 DrawText "Vertikal step: " + (steps + 1),10,10 Flip 0 EndIf EndIf 'looking for best vertical path to delete (lowest cost) 'find startplace pathv = New Int[mapheight] Local currentmin:Int = $7FFFFFFF For x:Int = 0 Until mapwidth If patharray[x , mapheight-1] < currentmin currentmin = patharray[x , mapheight-1] pathv[mapheight - 1] = x EndIf Next 'find way through flow For y:Int = mapheight - 2 To 0 Step - 1 Local oldx:Int = pathv[y + 1] Local s:Int = 0 If oldx > 0 If patharray[oldx-1 , y] < patharray[oldx + s , y] s = - 1 If oldx < mapwidth - 1 If patharray[oldx + 1,y ] < patharray[oldx + s,y] s = 1 pathv[y] = oldx + s Next If drawtmpimages & 4 map = ResizePixmap(map ,mapwidth , mapheight) For y:Int = 0 Until mapheight For x:Int = 0 Until mapwidth WritePixel(map,x,y,pixel[x,y,0]*$1000000 + pixel[x,y,1]*$10000 + pixel[x,y,2]*$100 + pixel[x,y,3]) 'shows picture 'WritePixel(map,x,y,((patharray[x,y]*255)/(maxdist))*$10101 + $FF000000) 'shows flow 'WritePixel(map,x,y,((distarray[x,y]*255)/(8*255))*$10101 + $FF000000) 'shows difference If pathv[y] = x WritePixel(map,x,y,$FFFF0000)'shows path Next Next Cls DrawPixmap map , 0 , 0 DrawText "Vertikal step: " + (steps + 1),10,10 Flip 0 EndIf 'Delete row from all arrays Local oldpixel:Byte[ , , ] = pixel Local olddistarray:Long[ , ] = distarray Local oldpatharray:Int[ , ] = patharray pixel = New Byte[mapwidth-1 , mapheight,pixel.Dimensions()[2]] distarray = New Long[mapwidth-1 , mapheight] patharray = New Int[mapwidth-1, mapheight] For y:Int = 0 Until mapheight x = 0 For Local xc:Int = 0 Until mapwidth If pathv[y] <> xc pixel[x , y , 0] = oldpixel[xc , y , 0] pixel[x , y , 1] = oldpixel[xc , y , 1] pixel[x , y , 2] = oldpixel[xc , y , 2] pixel[x , y , 3] = oldpixel[xc , y , 3] distarray[x , y] = olddistarray[xc , y] patharray[x,y] = oldpatharray[xc,y] x:+ 1 EndIf Next Next mapwidth:-1 steps:+1 Wend 'Imagepixelwerte aus array wieder ins Bild �bertragen Rem For y:Int = 0 Until mapheight For x:Int = 0 Until mapwidth WritePixel(map,x,y,$FFFFFFFF) Next Next End Rem map = ResizePixmap(map , newWidth , newHeight) For y:Int = 0 Until mapheight For x:Int = 0 Until mapwidth WritePixel(map,x,y,pixel[x,y,0]*$1000000 + pixel[x,y,1]*$10000 + pixel[x,y,2]*$100 + pixel[x,y,3]) Next Next Return map End Function |
||
- Zuletzt bearbeitet von Firstdeathmaker am Sa, Okt 11, 2008 12:08, insgesamt einmal bearbeitet
![]() |
Farbfinsternis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Bereits sehr beeindruckend.
Nächste Aufgabe: Echtzeit ![]() |
||
Farbfinsternis.tv |
![]() |
Firstdeathmaker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich glaube Echtzeit kann man mit BMax dabei vergessen. ![]() |
||
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon Gewinner des BCC #57 User posted image |
![]() |
ZaP |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich habe den Algorithmus ebenfalls implementiert, hier also mein Ansatz:
BlitzMax: [AUSKLAPPEN] 'Seamcarving Image Resizing Algorithm Einfach mal das Fenster verkleinern, dann rechnet das Teil los. Geht insgesamt schon ziemlich fix, aber leider nur fast Echtzeitfähig. Und es geht nur horizontal ![]() |
||
Starfare: Worklog, Website (download) |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group