AI Upscaled Textures

Show off your mod creations or just a work in progress.
BadLuckBurt
Posts: 433
Joined: Sun Nov 05, 2017 8:30 pm

Re: AI Upscaled Textures

Post by BadLuckBurt » Thu Mar 05, 2020 9:52 pm

So, Phedreeke made stuff like this?

Image

ImageMagick 'convert' command:

Code: Select all

convert 49-0.png -alpha extract 49-0_mask.png
What happens if this is upscaled with the same algorithm as sprites themselves?

User avatar
King of Worms
Posts: 3055
Joined: Mon Oct 17, 2016 11:18 pm
Location: Scourg Barrow (CZ)
Contact:

Re: AI Upscaled Textures

Post by King of Worms » Thu Mar 05, 2020 11:19 pm

BadLuckBurt wrote:
Thu Mar 05, 2020 9:52 pm
So, Phedreeke made stuff like this?

Image

ImageMagick 'convert' command:

Code: Select all

convert 49-0.png -alpha extract 49-0_mask.png
What happens if this is upscaled with the same algorithm as sprites themselves?
Hey, that link to AI upscaler looks really promissing, but it doesnt have a interface and thats usually prohibiting me from using it,because Im noob at this.

I think if we can get the alpha masks, and use same algo on them, and than combine it, it should yield a good results in theory ;)

User avatar
MasonFace
Posts: 417
Joined: Tue Nov 27, 2018 7:28 pm
Location: Tennessee, USA
Contact:

Re: AI Upscaled Textures

Post by MasonFace » Fri Mar 06, 2020 3:16 am

I had to look all the way back in this thread, starting at page 26 when a mysterious stranger named Phredreeke arrived on the scene.

Here's all his explanations of his method that I've been able to gather from this thread:
It's fairly automated, I put together a folder with images to be upscaled, this is then run through a number of scripts

1. creates a mask from the image in question
2. antialias the edges of the image, this is then fed to ESRGAN
3. the result of ESRGAN is run through a second script that sharpens, downscales and applies respective game's palette
4. finally, the mask from step 1 is applied to the downscaled image
I antialias the image, followed by upscaling to create the mask, at the end I apply a threshold effect of 127 to make the mask binary
phredreeke wrote:
Sat Mar 16, 2019 4:47 am
MasonFace wrote:
Tue Mar 12, 2019 2:48 pm
You said before that you aren't using a neural network to upscale the masking layer, so are you using interpolation to upscale it? If so, which interpolation model? I'm using GIMP, so I may not have the same interpolation models; all of them produce poor results for upscaling the anti-aliased masking layer. I've even tried using AA, then upscaling 150%, running AA again, upscaling 150%, running AA again, . . . until I reach the target resolution, but it just looks bad.
I use SmartSize, which to my understanding uses Bicubic when upscaling and Bilinear when downscaling. I only upscale at integer sizes (actually that's a slight lie with the latest mask, as I omitted 2 pixels on each axis for the last upscale, which I then pad back to the intended size)

For antialiasing I actually create a separate layer (I use the color selection tool then use shape-based antialias in PSP, and fill a layer on the inside setting and another layer on the outside setting then take the difference between those two) and use as a mask to soften the underlaying image (the actual mask for the upscaled image).
phredreeke wrote:
Tue Mar 19, 2019 6:11 pm

Anyway, here is the first part of my script. Perhaps someone with enough knowledge of GIMP could make an equivalent script there. (unfortunately no comments because most of it was recorded in one go)

Code: Select all

    App.Do( Environment, 'LayerDuplicate', {
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'NewRasterLayer', {
            'General': {
                'Opacity': 100, 
                'Name': r'Raster 1', 
                'IsVisible': App.Constants.Boolean.true, 
                'IsTransparencyLocked': App.Constants.Boolean.false, 
                'LinkSet': 0, 
                'UseHighlight': App.Constants.Boolean.false, 
                'PaletteHighlightColor': (255,255,64), 
                'GroupLink': App.Constants.Boolean.true, 
                'BlendMode': App.Constants.BlendMode.Normal
                }, 
            'BlendRanges': {
                'BlendRangeGreen': (0,0,255,255,0,0,255,255), 
                'BlendRangeRed': (0,0,255,255,0,0,255,255), 
                'BlendRangeBlue': (0,0,255,255,0,0,255,255), 
                'BlendRangeGrey': (0,0,255,255,0,0,255,255)
                }, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'Fill', {
            'BlendMode': App.Constants.BlendMode.Normal, 
            'MatchMode': App.Constants.MatchMode.None, 
            'Material': {
                'Color': (255,255,255), 
                'Pattern': None, 
                'Gradient': None, 
                'Texture': None, 
                'Identity': r'Material'
                }, 
            'UseForground': App.Constants.Boolean.true, 
            'Opacity': 100, 
            'Point': (1,1), 
            'SampleMerged': App.Constants.Boolean.false, 
            'Tolerance': 0, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'SelectLayer', {
            'Path': (0,-1,[],App.Constants.Boolean.false), 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Silent, 
                'AutoActionMode': App.Constants.AutoActionMode.Default
                }
            })

    App.Do( Environment, 'LayerSetVisibility', {
            'Command': App.Constants.ShowCommands.Hide, 
            'Path': (0,1,[],App.Constants.Boolean.false), 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Silent, 
                'AutoActionMode': App.Constants.AutoActionMode.Default
                }
            })

    App.Do( Environment, 'SelectAll', {
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'SelectColorRange', {
            'Action': App.Constants.ColorRangeAction.Subtract, 
            'ReferenceColor': (0,0,0), 
            'Softness': 1, 
            'Tolerance': 0, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'ShapeBasedAntialias', {
            'AntialiasType': App.Constants.AntialiasType.Inside, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'SelectLayer', {
            'Path': (0,1,[],App.Constants.Boolean.false), 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Silent, 
                'AutoActionMode': App.Constants.AutoActionMode.Default
                }
            })

    App.Do( Environment, 'SelectPromote', {
            'KeepSelection': None, 
            'LayerName': None, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'SelectLayer', {
            'Path': (0,-2,[],App.Constants.Boolean.false), 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Silent, 
                'AutoActionMode': App.Constants.AutoActionMode.Default
                }
            })

    App.Do( Environment, 'SelectAll', {
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'SelectColorRange', {
            'Action': App.Constants.ColorRangeAction.Subtract, 
            'ReferenceColor': (0,0,0), 
            'Softness': 1, 
            'Tolerance': 0, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'ShapeBasedAntialias', {
            'AntialiasType': App.Constants.AntialiasType.Outside, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'SelectLayer', {
            'Path': (0,1,[],App.Constants.Boolean.false), 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Silent, 
                'AutoActionMode': App.Constants.AutoActionMode.Default
                }
            })

    App.Do( Environment, 'SelectPromote', {
            'KeepSelection': None, 
            'LayerName': None, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'SelectLayer', {
            'Path': (0,-1,[],App.Constants.Boolean.false), 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Silent, 
                'AutoActionMode': App.Constants.AutoActionMode.Default
                }
            })

    App.Do( Environment, 'NewRasterLayer', {
            'General': {
                'Opacity': 100, 
                'Name': r'Raster 2', 
                'IsVisible': App.Constants.Boolean.true, 
                'IsTransparencyLocked': App.Constants.Boolean.false, 
                'LinkSet': 0, 
                'UseHighlight': App.Constants.Boolean.false, 
                'PaletteHighlightColor': (255,255,64), 
                'GroupLink': App.Constants.Boolean.true, 
                'BlendMode': App.Constants.BlendMode.Normal
                }, 
            'BlendRanges': {
                'BlendRangeGreen': (0,0,255,255,0,0,255,255), 
                'BlendRangeRed': (0,0,255,255,0,0,255,255), 
                'BlendRangeBlue': (0,0,255,255,0,0,255,255), 
                'BlendRangeGrey': (0,0,255,255,0,0,255,255)
                }, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'SelectAll', {
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'Fill', {
            'BlendMode': App.Constants.BlendMode.Normal, 
            'MatchMode': App.Constants.MatchMode.None, 
            'Material': {
                'Color': (0,0,0), 
                'Pattern': None, 
                'Gradient': None, 
                'Texture': None, 
                'Identity': r'Material'
                }, 
            'UseForground': App.Constants.Boolean.false, 
            'Opacity': 100, 
            'Point': (1,1), 
            'SampleMerged': App.Constants.Boolean.false, 
            'Tolerance': 0, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'SelectLayer', {
            'Path': (0,1,[],App.Constants.Boolean.false), 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Silent, 
                'AutoActionMode': App.Constants.AutoActionMode.Default
                }
            })

    App.Do( Environment, 'LayerMergeDown', {
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'SelectLayer', {
            'Path': (0,1,[],App.Constants.Boolean.false), 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Silent, 
                'AutoActionMode': App.Constants.AutoActionMode.Default
                }
            })

    App.Do( Environment, 'LayerProperties', {
            'General': {
                'Opacity': None, 
                'Name': None, 
                'IsVisible': None, 
                'IsTransparencyLocked': None, 
                'LinkSet': None, 
                'UseHighlight': None, 
                'PaletteHighlightColor': None, 
                'GroupLink': None, 
                'BlendMode': App.Constants.BlendMode.Difference
                }, 
            'BlendRanges': None, 
            'Path': (0,0,[],App.Constants.Boolean.false), 
            'BrightnessContrast': None, 
            'ChannelMixer': None, 
            'ColorBalance': None, 
            'CurveParams': None, 
            'HSL': None, 
            'Threshold': None, 
            'Levels': None, 
            'Posterize': None, 
            'Overlay': None, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Silent, 
                'AutoActionMode': App.Constants.AutoActionMode.Default
                }
            })

    App.Do( Environment, 'LayerMergeDown', {
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'SelectLayer', {
            'Path': (0,-1,[],App.Constants.Boolean.false), 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Silent, 
                'AutoActionMode': App.Constants.AutoActionMode.Default
                }
            })

    App.Do( Environment, 'DeleteLayer', {
            'Path': None, 
            'MergeMask': App.Constants.Boolean.true, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'DeleteLayer', {
            'Path': None, 
            'MergeMask': App.Constants.Boolean.true, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'LayerDuplicate', {
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'Soften', {
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'MaskFromImage', {
            'CreateMaskFrom': App.Constants.CreateMaskFrom.Luminance, 
            'InvertMaskData': App.Constants.Boolean.false, 
            'SourceImage': 0, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'SelectLayer', {
            'Path': (1,1,[],App.Constants.Boolean.false), 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Silent, 
                'AutoActionMode': App.Constants.AutoActionMode.Default
                }
            })

    App.Do( Environment, 'DeleteLayer', {
            'Path': None, 
            'MergeMask': App.Constants.Boolean.true, 
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })

    App.Do( Environment, 'LayerMergeDown', {
            'GeneralSettings': {
                'ExecutionMode': App.Constants.ExecutionMode.Default, 
                'AutoActionMode': App.Constants.AutoActionMode.Match
                }
            })
I believe he recorded his macro in Paint Shop Pro to do all this.

If you have PSP, maybe you can reproduce his method.

User avatar
MasonFace
Posts: 417
Joined: Tue Nov 27, 2018 7:28 pm
Location: Tennessee, USA
Contact:

Re: AI Upscaled Textures

Post by MasonFace » Fri Mar 06, 2020 3:46 am

I think I've got a method that will work.

I pretty much followed Phredreeke's method, but I'm using "Median Blur" filter in Gimp instead of anti-aliasing to smooth the masking layer bounds.

I'm writing this for my own reference now in case I forget:

1. Set alpha portion to black, invert selection then fill with white.
2. Add 4 pixels of padding to all sides.
3. Scale the image by a factor of 4 using "LoHalo" interpolation model.
4. Use Median Blur filter: Neighborhood = "Circle", Radius = 6, percentile = 50, alpha percentile = 50
5. Posterize color to get straight black/white.
6. Cut out the original 4 pixels used for padding (now 16 pixels) all around the border of the image.
235_37-0_Upscaled_Transparent.PNG
235_37-0_Upscaled_Transparent.PNG (240.36 KiB) Viewed 120 times
Burt,

If I'm able to produce masking layers, can you use ImageMagick to combine them with the upscaled images to restore the transparency?

Update: As soon as I hit submit I remember an important detail... the GIMP API does not have a method for the median blur so I can't batch this with code. :cry: I remember now that I went down this road with the MOBs... I was hoping that maybe they've added it to the API since I've updated GIMP, but it still isn't available.

Maybe ImageMagick has a filter similar to median blur? Median blur pretty much just smooths out jagged contours into smooth curves. Perhaps you can use IM's feather/blur, then clip the transparency at some threshold?
Last edited by MasonFace on Fri Mar 06, 2020 3:55 am, edited 1 time in total.

BadLuckBurt
Posts: 433
Joined: Sun Nov 05, 2017 8:30 pm

Re: AI Upscaled Textures

Post by BadLuckBurt » Fri Mar 06, 2020 3:50 am

edit: My simple to do answer was for your original question. Not for the question you posed after

If you dont mind, I dont want to get too involved with creating these masks. What I thought would be just assisting KoW with the last stretch of the paperdoll stuff is quickly ballooning into something else.

ImageMagick is freely available and I never used it before, I just knew it existed. Im figuring out commands by Googling and trial and error and if anyone need help with that I dont mind but I cant commit to create those masks.

User avatar
MasonFace
Posts: 417
Joined: Tue Nov 27, 2018 7:28 pm
Location: Tennessee, USA
Contact:

Re: AI Upscaled Textures

Post by MasonFace » Fri Mar 06, 2020 4:25 am

I think I've got a way to do it with just simple blur which is batchable. Basically the same process but using gaussian blur instead of median blur. The results aren't quite as good, but it may be passable.

User avatar
MasonFace
Posts: 417
Joined: Tue Nov 27, 2018 7:28 pm
Location: Tennessee, USA
Contact:

Re: AI Upscaled Textures

Post by MasonFace » Fri Mar 06, 2020 4:30 am

If you dont mind, I dont want to get too involved with creating these masks. What I thought would be just assisting KoW with the last stretch of the paperdoll stuff is quickly ballooning into something else.

ImageMagick is freely available and I never used it before, I just knew it existed. Im figuring out commands by Googling and trial and error and if anyone need help with that I dont mind but I cant commit to create those masks.
Yeah, believe me, this stuff gets out of hand real quick. And KoW knows that better than anyone. I definitely don't blame you.

I'll try to chip away at making a small sample batch as I get time. I'll give the results over to KoW to test and see if they look okay in game before I try to commit fully, myself. I do have concerns with how the paper doll will fit through the sleeve holes in some garments. I just don't see how we can make it look right in every circumstance... but we'll see.

BadLuckBurt
Posts: 433
Joined: Sun Nov 05, 2017 8:30 pm

Re: AI Upscaled Textures

Post by BadLuckBurt » Fri Mar 06, 2020 4:52 am

Thank you for understanding. I am sticking around to help where I can but Im not good with graphic stuff at all, Im a coder and troubleshooter for the most part.

I think youre right about creating a small batch first. When I looked up the alpha extraction for IM, the example stated the reverse, mask injection is just as easy to execute so once there is a proper mask, that part will be trivial

User avatar
King of Worms
Posts: 3055
Joined: Mon Oct 17, 2016 11:18 pm
Location: Scourg Barrow (CZ)
Contact:

Re: AI Upscaled Textures

Post by King of Worms » Fri Mar 06, 2020 9:51 am

Thank you MasonFace for digging that info out and for sharing the knowledge! And BadLuck, I understand you dont want to get too involved in this.

What is really messing with my head is the FACT that I have the proper and working MALE armors on my HDD and I have NO idea how they got the the state they are at - smooth outlines and no artefatcs, they are just good.

Than I have the FEMALE version, some of those are at the same level as MALE, but some have bugged colors (that was because a wrong export from DFU which is now solved) - Some of the armors apparently have the issue we were getting here recently - the black background was not homogenic and the treshold was too big to get it out and it messed up the sprites.

I still think there was some easier method to get those armors. But how it was done, is a mystery.

Not sure what I should do now? Im willing to put in some work, but I dont know where to direct it

User avatar
King of Worms
Posts: 3055
Joined: Mon Oct 17, 2016 11:18 pm
Location: Scourg Barrow (CZ)
Contact:

Re: AI Upscaled Textures

Post by King of Worms » Fri Mar 06, 2020 10:02 am

I found a description some 60 pages back burried in the dream thread
viewtopic.php?f=27&t=1168&start=940#p28880

The relevant part is:
After you've done this the images will have a solid black background that needs to be removed. I used a utility called imagemagick for nearly all of the images, but a few with thinner lines needed manual work with the "magic wand" selection tool in Paint.Net. The imagemagick code I used is as follows:

for %%f in (*.png) do convert %%f -fuzz 10 -transparent rgb(0,0,0) output/%%f

Make sure to add a folder named output next to the file. Any .png in the folder with the bat will be converted, and the results will be found in the output folder.

This will clean up some of the images perfectly. But many defects will result due to automated processes. To clean frayed, pixelated, or otherwise slightly garbled edges, I use a Paint.Net plugin called: AA's_Assistant by dpy.

Now after much editing and Anti-aliasing, you'll have all your images.
So I think what I should do is, have the ESRGANs, use ImageMagick, it will make 90% of the items corectly. Those which are not done corectly I will deal with later.

Use the AA asistant to clean the edges

Any opinions on the:
for %%f in (*.png) do convert %%f -fuzz 10 -transparent rgb(0,0,0) output/%%f

Is it the same/similar to what u tryed BadLuck? How to apply it on the whole folder please?

Also, FEMALE armor - which is the most crucial part, has 1400 files. Thats just 10% of the whole paperdoll.. So some manual input will not kill me.
Plus I can exclude shields, helmets - thats another 400 less!
Last edited by King of Worms on Fri Mar 06, 2020 10:25 am, edited 2 times in total.

Post Reply