View Full Version : Median() plugin
ajk
11th February 2014, 14:18
Hi,
I've been capturing old tapes using the median method, ie. capturing the same tape several times to get rid of glitches and noise that do not appear in the same place each time.
There is no Median() function in AviSynth, although there are ways to script it using other plugins. That works fine but I thought I'd take a stab at a bespoke plugin for this purpose. I have no experience whatsoever with AviSynth plugin development but I have managed to get something done over the last week.
If anyone would be so kind as to try this out, I could iron out any bugs and then make a proper readme and stuff for it.
Things to notice:
- the plugin will accept between 3 and 25 clips
- chroma processing can be turned off with "chroma=false", or in the case of RGB32 this will turn off processing for the alpha channel
- there is also a more configurable MedianBlend() function, see examples in the readme or posts further below
Any feedback is appreciated!
# Usage:
Median(clip1,clip2,clip3..., chroma=true/false)
Packages also available for download over here (http://ajk.kapsi.fi/projects/avisynth/median-plugin/).
StainlessS
11th February 2014, 17:18
Would have been nice if source were supplied, I was gonna give it the once over.
ajk
11th February 2014, 17:21
Will do once I've cleaned it up. I also realised that this is probably the debug build, not sure if it will work properly without having Visual Studio or at least some bits of it installed. Will update again later.
StainlessS
11th February 2014, 18:13
Just taken a look, Uses MSVCP120D.dll and MSVCR120D.dll, think the D in 120D signifies debug runtime library.
Above runtimes for Visual Studio 2013, I'm guessing that not too many people have those runtimes installed (I dont, yet).
As VS 2013 will give lots of people problems with missing runtimes, suggest static link with runtime libraries.
EDIT: /MT
http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx
EDIT: Or, point people to the runtimes here:- http://www.microsoft.com/en-gb/download/details.aspx?id=40784
EDIT: It seems that I do have VS 2013 runtimes installed, but not the debug versions, so must not be included in the runtimes
as linked above, must not release debug versions.
ajk
12th February 2014, 08:10
Yeah sorry about that, I rarely work with Windows desktop programming so I tend to forget these things. I have now uploaded a release version of the plugin linked with /MT, so that should hopefully work without extra effort. There is also a separate archive with the source code.
ajk
13th February 2014, 13:55
I uploaded a new version now which can also handle planar and RGB clips. I didn't really have such raw clips to test with but at least when converted within AviSynth my YUY2 test clips seemd to process correctly. There is also a separate download link for the files now.
TurboPascal7
13th February 2014, 14:05
You should call NewVideoFrame inside GetFrame rather than storing it as a class variable.
Also, current build doesn't seem to work. Access violation writing 0x0000000.
StainlessS
13th February 2014, 14:37
@Ajk, Thanx, I'll take a peek when it clears (those moderators have such an easy time of it here :))
Perhaps you will need a file host service if you are going to be posting zips, I currently use MediaFire but it has been getting a bit annoying of late,
Mediafire lately seems to have been embracing the dark side. I suggest you move your stuff to dropbox.com, much lighter and no popups. I did. :)
I'm currently in process of signing up to DropBox, requires a 36MB download exe (downloading now), presume something like GDrive.
ajk
13th February 2014, 17:19
@TP7
Ok, I could change that. Have to look into that access violation, seemed ok when I posted...
@StainlessS
That's why I also posted the secondary download link :) Maybe I need to make it stand out more...
StainlessS
13th February 2014, 17:40
Ooops, did not see that link, perhaps bright red animated gif for us blind people :)
Taken brief look, only real thing I've seen yet is redefinition of i error in Constructor (VS6 compiler, might as well make it compile everywhere),
and the NewVideoFrame issue posted by TurboPascal7.
Have not as yet tried out the dll, curious what args access Violation occurs with, num clips and colorpspace, or always.
I shall take the text to the pub to peruse in there, ta ta.
Groucho2004
13th February 2014, 17:58
I'm currently in process of signing up to DropBox, requires a 36MB download exe
No, it does not. You don't need that to upload and share your files.
StainlessS
13th February 2014, 18:02
Thank you Grouchy :), had not intended to use any installed app, but takes you straight to download page after
signup, so thiought may be necessary, shall give the exe at least a cursory try though as I've already downloaded it.
ajk, just move the other link adjacent to the attachments (did not re-read the full post, just attachment status).
Gavino
13th February 2014, 18:52
You should call NewVideoFrame inside GetFrame rather than storing it as a class variable.
Also, current build doesn't seem to work. Access violation writing 0x0000000.
The access violation is very likely a result of the first issue.
Since you are using and returning the same PVideoFrame for all frames, it won't be writable after the first frame, so GetWritePtr() returns a null pointer.
StainlessS
13th February 2014, 18:59
v2.5 dll running on v2.6 Avisynth will process v2.6 planar colorspace Chroma incorrect due to IsPlanar() rather than IsYV12().
Can use IsPlanar() if processing Luma only.
EDIT: 2.5 header will eg give GetRowSize as for Yv12.
something I use in constructor
# ifdef AVISYNTH_PLUGIN_25
if(vi.IsPlanar() && vi.pixel_type != 0xA0000008) {
// Here Planar but NOT YV12, If v2.5 Plugin Does NOT support ANY v2.6+ ColorSpaces
env->ThrowError("RT_Stats: show version unsupported for colorSpace in v2.5 plugin");
}
# endif
EDIT: Correction, v2.5 dll, Both IsPlanar and IsYV12 will return true for all planar colorspaces, should perhaps check that it is
actually YV12 you are dealing with when touching chroma.
ajk
13th February 2014, 19:46
Okay, I've fixed the output video frame issue. That actually came over from the "Average" plugin, which I came across while searching for a median function. But Average consists of two classes so there everything gets initialized properly each frame. Interesting that this worked for me during all my testing.
I've updated the attachments again (sorry moderators :)). I made a note of the chroma issue in the readme, but will otherwise leave it for now, since often luma processing is useful enough as it is. I did in fact test with YV16 and YV24 and got only partial results for the chroma planes (half or a quarter, which makes sense now). Have to look into this more later but those formats seem to be kinda uncommon anyway.
ajk
15th February 2014, 08:23
Not too much interest in this I guess? I've now extended the support to 25 clips, and added some extra functionality in the form of MedianBlend(). This will accept any number of clips between 3 and 25, discard some amount of highest and lowest values on a per-pixel basis, and average the rest together.
For example, you can achieve a minimum or maximum function, or combine averaging with median:
# Discard two highest values
MedianBlend(clip1,clip2,clip3, low=0, high=2)
# Discard two lowest values
MedianBlend(clip1,clip2,clip3, low=2, high=0)
# Discard highest and lowest value and average the two remaining ones
MedianBlend(clip1,clip2,clip3,clip4, low=1, high=1)
I'm sure this is pretty familiar with the regulars here, but just as a concrete example of what median does with three captures, here's an image:
http://forum.doom9.org/attachment.php?attachmentid=14044&d=1392448797
We start with three captures, all of which have various black and white streaks. But after sorting the pixel values we end up with three different images, the first one has all the black streaks, last one all the white streaks, and the middle (median) one is quite clean. Depending on how noisy the tape is, five or more captures can help further.
TurboPascal7
15th February 2014, 09:43
I was thinking about writing an optimized temporal-only median some time ago but didn't find any real use for it. Apparently people rarely want to calculate median of more than 5 frames and that can be implemented efficiently with existing tools.
IMHO, your plugin has at least two problems:
1) Most of the times (most of the use cases I've seen) people want to calculate temporal median of a single clip, i.e. "merge" frames 0, 1, 2, 3 and 4 together rather than taking them from completely different clips. With your plugin this is quite cumbersome and requires a few deleteframe/duplicateframe/trim calls to build those multiple clip arguments.
On the other hand if you have a temporal median filter, it's easy to use it with multiple clips by simply calling interleave().median().selectevery(), just like it works with e.g. motion-compensated denoising. This won't work when you need even number of clips but that can be worked around by something like variable forward/backward radii maybe.
I guess people having access to multiple recordings of the exactly same stream is quite uncommon.
2) Your plugin is slow. Optimizing purely temporal median is a trivial task and I don't know why you didn't do this. Probably doesn't matter that much on SD recordings but why pay more when you can pay less?
There are already ways of doing some of the cases more efficiently. Radius 2 is simply mt_average, radius 3 median is Clense(), which is very fast. Radius 5 median is not so trivial, but can be done efficiently with masktools and clense (from here (http://mechaweaponsvidya.wordpress.com/2014/01/31/enter-title-here/)):
function median5(clip a,clip b,clip c,clip d,clip e)
{
abmin = mt_logic(a,b,"min")
abmax = mt_logic(a,b,"max")
cdmin = mt_logic(c,d,"min")
cdmax = mt_logic(c,d,"max")
x = mt_logic(abmin,cdmin,"max")
y = mt_logic(abmax,cdmax,"min")
interleave(x,y,e).clense().selectevery(3,1)
}
You can figure other radii yourself, simply implement the same sorting network with masktools. Yes, it will probably be less memory-efficient but a lot faster in general thanks to very fast SIMD min/max operations.
Now, this won't work with YUY2 and this is where YV16 shines - you simply convert your YUY2 clip to YV16, process it with planar-only (and YV16-aware) filters and convert back if you want to keep YUY2. No additional code for YUY2 required so people can optimize planar to skies to speedup most use cases (no planar RGB though). This also ensures that you're using same processing code for all colorspaces and people won't end up with different results if they happen to pass YV16 and not YUY2 to your plugin. For example your YUY2 chroma output is quite different from YV12 because you calculate median of U and V channels together when processing YUY2 and separately when processing planar formats. This is confusing.
If you want to add some optimizations yourself, feel free to look how it's done in MedianBlur2 (https://github.com/AviSynth/MedianBlur2/blob/7db2c995e72fbc615ee138f748d9c7474de9be2b/MedianBlur2/special.h#L198). Same sorting business, nothing really fancy here. If all frames are 16-byte aligned (almost always in avisynth 2.6, especially avs+), you don't even have to do any border processing and it's trivial in any case.
Anyway, good luck, glad to see people writing avs plugins in 2014. :)
ajk
15th February 2014, 11:47
Thank you for your comments! I agree that the plugin is not particularly optimised at least right now, but I wanted to get all the functionality that I need implemented first. It would be great to have an optimised median function as a core filter, but I guess there hasn't been enough need for one.
There are various reasons for making a plugin rather than using scripting. First, I simply like the convenience of having a single, straightforward function to call for all kinds of different situations and colour spaces. Second, the speed could probably be improved but the whole motivation for this exercise was exactly the case of an analog tape, where you can "easily" make multiple captures, as many as you need to get rid of all the noise. This is a common method, many threads regarding the matter on related forums. Of course, this does not really come up with HD material which is almost always digital. I understand that there may be other use cases for a median function where another approach can be better.
There shouldn't be any difference in the chroma output between interleaved and planar input. The processing for each "stack" of any sort of samples is the same (the ProcessPixel() function, perhaps not the most accurate name). Have you got a sample of where there was a difference?
TurboPascal7
15th February 2014, 12:06
There shouldn't be any difference in the chroma output between interleaved and planar input. The processing for each "stack" of any sort of samples is the same (the ProcessPixel() function, perhaps not the most accurate name). Have you got a sample of where there was a difference?
The difference is how you build the array you pass to that function.
for (unsigned int i = 0; i < depth; i++)
{
luma[i] = srcp[i][x * 2];
chroma[i] = srcp[i][x * 2 + 1];
}
In YUY2, data is stored as YUYVYUYVYUYV, so your chroma array will get UVUVUVUV... instead of UUUUU/VVVVV as it should.
ajk
15th February 2014, 12:12
for (int x = 0; x < width; x++)
{
for (unsigned int i = 0; i < depth; i++)
{
luma[i] = srcp[i][x * 2];
chroma[i] = srcp[i][x * 2 + 1];
}
dstp[x * 2] = ProcessPixel(luma);
dstp[x * 2 + 1] = ProcessPixel(chroma);
}
The processing here essentially advances one sample-pair at a time. In each iteration there is one luma sample, and one chroma sample from some number of clips. The chroma sample type alternates between U and V. To get an array with U and V mingled would mean that the different clips scrp points to are not properly aligned, no?
TurboPascal7
15th February 2014, 12:18
Oh sorry, I'm dumb and keep thinking about spatial processing.
I guess I should have actually checked with YV16 instead of YV12 where difference comes from different chroma subsampling. You can just ignore that part.
ajk
15th February 2014, 17:03
Your plugin is slow
I'll have a closer look at how much space for optimisation there is. But what is a reliable way to gauge the speed of a filter?
I did some testing with VirtualDub's "run video analysis pass". I took a short segment of my five sample clips and converted them to YV12, Interleave()'d them all and ran the analysis, this gave around 100 fps. This was just to establish how fast I can even load five clips simultaneously, without any heavy filtering.
Then I ran the Median5() you posted against my filter, both ran pretty much at the same speed, about 21 fps.
I also took Median1() from here (http://forum.doom9.org/showthread.php?t=159780), and ran that against my filter with three input clips. The result again was quite similar, about 37 fps.
I made sure to close the file in VirtualDub between each test as caching seems to affect the results, running a second pass immediately after the first yields much faster results.
What did you use to see such a big difference in speed? I'm not running AviSynth+ yet so that might be a factor.
Here's the script I used, for reference.
SetMTMode(3,0)
clip1 = AVISource("capture1.avi").ConvertToYV12(interlaced=true)
clip2 = AVISource("capture2.avi").ConvertToYV12(interlaced=true)
clip3 = AVISource("capture3.avi").ConvertToYV12(interlaced=true)
clip4 = AVISource("capture4.avi").ConvertToYV12(interlaced=true)
clip5 = AVISource("capture5.avi").ConvertToYV12(interlaced=true)
SetMTMode(2)
#interleave(clip1,clip2,clip3,clip4,clip5)
#median5(clip1,clip2,clip3,clip4,clip5)
#median(clip1,clip2,clip3,clip4,clip5)
median1(clip1,clip2,clip3)
#median(clip1,clip2,clip3)
Reel.Deel
15th February 2014, 17:50
But what is a reliable way to gauge the speed of a filter?
AVSMeter (http://forum.doom9.org/showthread.php?t=165528) is a very good tool for that purpose.
ajk
15th February 2014, 18:07
@Reel.Deel
Sweet! Nifty tool. I ran the same four scripts again and for median of five I got 20.53 fps (script) vs. 20.31 fps (plugin), and for median of three 37.00 fps (script) vs. 38.20 fps (plugin). Doesn't seem too bad to me. Maybe someone else can verify.
TurboPascal7
15th February 2014, 23:25
You're most likely limited by speed of 5 AviSource calls, while I test only with processing one clip. Or your PC doesn't have SSE2 but that would be kinda strange.
ajk
16th February 2014, 07:35
Ok, well I did one more test with just one clip to simulate a temporal median:
#median5(clip1,clip1.Trim(1,0),clip1.Trim(2,0),clip1.Trim(3,0),clip1.Trim(4,0)) # 163.0 fps
median(clip1,clip1.Trim(1,0),clip1.Trim(2,0),clip1.Trim(3,0),clip1.Trim(4,0)) # 152.4 fps
The masktools version wins by a little bit but I still wouldn't call mine slow with a bold typeface :) This is on an i7-2600K.
Anyway, this was really intended to continue what Average (http://forum.doom9.org/showthread.php?t=100626) was doing. The question of a median function arose in that thread years ago but apparently was never implemented (probably exactly because there were alternatives at least for the most common 3 and 5 clip cases).
ajk
15th March 2014, 13:52
I've updated the plugin to 0.5, chroma=false was not working right with planar clips.
I also added a TemporalMedian() mode in case it is useful to someone. You could use it as a denoiser within one clip if the video doesn't have much movement and you keep the radius small. Otherwise the results can be pretty funky :) But realistically for actual denoising other filters are more appropriate.
The filter accepts a radius between 1 and 12, corresponding to a median of 3 to 25 frames.
TemporalMedian(clip, radius=2) # Median of current, two preceding, and two following frames
althor1138
17th February 2017, 22:01
Hi Ajk. Great idea for a filter and seems to be the only median type of filter that goes in the direction I want it to. I have one question though.
Does the temporalmedian have an option for high and low parameters like the medianblend? This would make it easy to interleave 3 or more separate sources(separate laserdisc releases, for example), motion compensate them, and feed them to your filter while retaining the ability to throw away high or low pixel values. This should allow for removal of dropouts present on the disc and errors during playback.
jmac698
18th February 2017, 09:51
I should point out my summary of this technique and further features you could add.
http://www.digitalfaq.com/forum/video-restore/2734-averaging-multiple-captures-3.html#post45498
You could add this
-With 7 or more captures, eliminating extremes and averaging is better at reducing noise than median.
-...gives more weight to the middle values
So if I could give weights to the sorted values, for example (0,1,1,0) would be the average of the two middle values, excluding the black/white extremes. That syntax would include all previous features as well.
I should add that my magical number 7, refers to median giving 80% the noise reduction as average, or sqr(2/pi), and 7 is the point where avg(5) beats median(7). In my experience though, streaks can still appear in some of the middle values. A much better streak reduction would include some attempt at masking streaks.
You could destreak with median, subtract from original, clean it up, then use that as a mask and average all the pixels that aren't streaked, to get 20% better noise reduction.
ajk
18th February 2017, 13:06
@althor1138
Hi, the temporal version of the filter does not currently have those parameters. But if I understand your idea correctly, you should be able to interleave the clips, motion compensate, and then separate them again with SelectEvery(). After that you can use the other versions of the filter on those clips as normal.
If you've got some sample material, perhaps you could give this a try and see how it turns out?
@jmac698
I implemented that (0,1,1,0) suggestion of yours already three years ago (http://forum.videohelp.com/threads/362361-Median%28%29-plugin-for-Avisynth?p=2302015&viewfull=1#post2302015) when you asked about it over at VideoHelp :) Or do you need the weight values to be floats or something?
Adding masking functionality and such gets a bit complicated within a single plugin, I'd say it's better to go with separate plugins and scripting when venturing there.
Reel.Deel
18th February 2017, 22:58
@ajk
Since the source code for the latest version (v0.6) is not available can you please provide a 64-bit binary? Y8, YV16, and YV24 colorspaces would be great also. :)
ajk
20th February 2017, 14:02
@Reel.Deel
Yeah, the only difference in 0.6 is the added sync stuff, which is still a bit messy and not well commented. But I'll try to make a more modern build when I have some time; adding the colour spaces is trivial.
Aktan
10th February 2018, 03:33
I'm getting an access violation when I try to use a 64-bit dll of version 0.5 that I compiled locally. I'm using AVS+. I'm guessing it's due to using Avisynth interface version 3, or is it something else silly that I've done?
StainlessS
10th February 2018, 13:37
Yep, you will need latest AVS+ headers for 64 bit (#include "avisynth.h"),
and add path to AVS/ additional headers to options (I dont have VS set up at the moment, but need add to both 32bit and 64 options).
in AVS/ folder
alignment.h
avisynth.h
capi.h
config.h
cpuid.h
minmax.h
types.h
win.h
EDIT: I usually copy avisynth.h into current/source folder and is also in avs/ directory as set in options.
EDIT: From FrameStore
#include <windows.h>
#include "avisynth.h" // Avs+26, also needs Options/Projects & Solutions/Include/ directory set to additional avs headers
Make sure set for both 32 and 64 bit options (there is an easily missable 32/64 bit drop down selector in the options).
Aktan
10th February 2018, 13:42
Yep, you will need latest AVS+ headers for 64 bit (#include "avisynth.h"),
and add path to AVS/ additional headers to options (I dont have VS set up at the moment, but need add to both 32bit and 64 options).
in AVS/ folder
alignment.h
avisynth.h
capi.h
config.h
cpuid.h
minmax.h
types.h
win.h
EDIT: I usually copy avisynth.h into current/source folder and is also in avs/ directory as set in options.
:thanks:, I'll try that!
Edit: I did do some debugging, and it's related to how arrays are handle. If I change it to do a constant number of clips that I need (ccc instead of c+), it works fine. This is before I try the AVS+ headers.
Edit 2: So apparently for whatever reason, AVS+ doesn't like the line:
AVSValue array = args[0];
Changing all references of array to args[0] fixed the problem. It's probably pointer related, but I'm not good enough of a C++ programmer to tell, lol.
ajk
11th February 2018, 07:37
Got an email about a thread update :) I had to reinstall my system last year and haven't really got the development stuff set up since then. I should look into an AVS+ version of the plugin at some point but this just hasn't been much of a priority unfortunately :(
But here is the source for v0.6 nevertheless, it's the same as far as the actual median processing goes but it now includes the sync and debug stuff: http://ajk.kapsi.fi/projects/avisynth/median-plugin/Median-0.6-src.zip
@Aktan
I'll be happy to host any versions and changes you come up with, too :)
jpsdr
11th February 2018, 12:30
I've made a VirtualDub median filter a long time ago to remove white dots on VHS, but i've added a parameter : a threshold.
And there is 3 mode : square, line horizontal, line vertical.
You can find it on my github.
FredThompson
11th February 2018, 15:41
Not too much interest in this I guess?
Quite the contrary. There were only 4(?) days between your initial post and this one and there were clearly runtime issues. Your idea and code caught the attention of some of the most active/best coders here. If an idea is good and the time is right, it generally catches on.
To me, this looks fantastic. I've got a few hundred tapes to process and the cleanup time has always been so great that I haven't been motivated to do it...even though I'm aware the longer the tapes sit, the sticker they get and the more magnetic migration happens.
Given the cost of drive space now, setting up a dedicated PC and capturing a complete tape 5 times then calculating median as an interim file is very attractive.
Aktan
11th February 2018, 19:06
Got an email about a thread update :) I had to reinstall my system last year and haven't really got the development stuff set up since then. I should look into an AVS+ version of the plugin at some point but this just hasn't been much of a priority unfortunately :(
But here is the source for v0.6 nevertheless, it's the same as far as the actual median processing goes but it now includes the sync and debug stuff: http://ajk.kapsi.fi/projects/avisynth/median-plugin/Median-0.6-src.zip
@Aktan
I'll be happy to host any versions and changes you come up with, too :)
Thanks for releasing the source code for 0.6! Honestly, with the new VSC2017, setting up the dev takes like 30 mins. Just get the VS
Installer and click some check boxes, and bam! Done!
Sure, I'll compile 0.6 to 64-bit and link you. I don't think I will update it to AVS+ headers though. I'll just fix it to work with the older header like I did with 0.5.
I've made a VirtualDub median filter a long time ago to remove white dots on VHS, but i've added a parameter : a threshold.
And there is 3 mode : square, line horizontal, line vertical.
You can find it on my github.
Cool! Great addition!
Quite the contrary. There were only 4(?) days between your initial post and this one and there were clearly runtime issues. Your idea and code caught the attention of some of the most active/best coders here. If an idea is good and the time is right, it generally catches on.
I think you missed the year the initial post happened...
ajk
11th February 2018, 19:10
@FredThompson
Four days and four years :D But yes, the core concept has worked well for me. It's not always worth it for tapes that play clean anyway, but for some of the more stubborn ones it has worked great.
@Aktan
Yeah, I will get round to it some day :) I'll be happy to host your compilation in the mean time so everything stays in the same place.
Aktan
11th February 2018, 19:39
@Aktan
Yeah, I will get round to it some day :) I'll be happy to host your compilation in the mean time so everything stays in the same place.
Here you go:
<Link Removed>
It contains the changes I did and the compiled 64-bit DLL. I did compile with VSC2017 and Win10SDK so I think it will work fine Vista 64-bit+ but I'm just guessing.
ajk
11th February 2018, 19:56
@Aktan
Thanks - I uploaded it with the others at http://ajk.kapsi.fi/projects/avisynth/median-plugin/Median-0.6-x64.zip
FredThompson
11th February 2018, 21:58
I think you missed the year the initial post happened...Oh, yeah. Guess I should finally admit I'm getting old and vision isn't quite what it used to be....Age is an economical version of beer goggles...
ChaosKing
2nd March 2018, 20:40
Big thx for this filter, it worked very good on a Anime DVD opening/ending. With MedianBlend(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, low=3, high=3) nearly all compression artefacts were gone!
jmac698
6th August 2018, 06:09
Just wanted to mention an O(n) sorting algorithm, which is essential for finding a median.
#Fibonacci Sort
unsorted = [3, 1, 4, 1, 5, 9, 2, 6, 0]
counts = [0] * 10
fib = [0] * (10 + 1)
sortd = [0] * len(unsorted)
#First pass: find the counts
for n in unsorted:
counts[n]+=1
#Second pass: do the Fibonacci magic
i = 0
total = 0
for n in counts:
fib[i] = total
total += n
i+=1
#Third pass: output sorted
for n in unsorted:
sortd[fib[n]] = n
fib[n] += 1
#Results
print(sortd)
I invented this years ago, but now realize it's called the counting sort. It doesn't need comparisons.
I believe @StainlessS asked me about this once, and said he collected sorting algorithms?
TheFluff
6th August 2018, 07:11
You are aware that there is a constant time algorithm for median filters, yes? As in O(1), does not scale with radius at all. tp7 linked his implementation on page 1, four years ago.
StainlessS
6th August 2018, 11:17
I believe @StainlessS asked me about this once, and said he collected sorting algorithms?
Dont recall that, I have some interest in sorting/searching but would not really say that I collect said stuff.
Nice to see you about again JMac :)
EDIT: I'll post at some point a version of PlanetCrop that runs with either avs+ or GScript.
EDIT: Posted PlanetCrop in RT_Stats thread.
jmac698
6th August 2018, 14:24
Not true - the paper says it's O(1) per pixel because they cache some results, but mine is O(1) in that sense also. since I only have 3 operations per pixel which are constant. Also a median is not the same as producing one sorted list of all pixels; in that sense both are O(n). Clearly you can't sort anything in O(1) because you must access the memory in steps, and you can't read a whole screen at once unless it's massively parallel.
Edit: I believe our algs are basically the same, count is the same as histogram
TomArrow
14th January 2019, 14:16
Hey there, I was wondering if it would be at all thinkable to introduce RGB64 support to this plugin. Have never done any plugin coding myself, so not sure if I could handle it, but on the surface it sounds like it shouldn't be too difficult. Could anyone help out or point me in the right direction to do it myself?
Aktan
14th January 2019, 23:32
Hey there, I was wondering if it would be at all thinkable to introduce RGB64 support to this plugin. Have never done any plugin coding myself, so not sure if I could handle it, but on the surface it sounds like it shouldn't be too difficult. Could anyone help out or point me in the right direction to do it myself?
I think it wouldn't be too hard as RGB64 is similar to RGB32 just different bits. I would just look at the source to see how RGB32 was done.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.