I initially rewrote this in Python but it was S L O W. Re-rewrote it in C and not it's a very nice little utility that I use on a regular basis, thanks for the video dude. Keep up the great work! Love how you are making this stuff accessible to everyone.
@Rai2M
2 жыл бұрын
wiki makes this stuff accessible
@DrSpooglemon
Жыл бұрын
Python can be made to run more efficiently if you understand its idiosyncrasies.
@luigidabro
Жыл бұрын
@@DrSpooglemonbut never faster than efficient C
@DrSpooglemon
Жыл бұрын
@@luigidabro Sure, but it can be faster than people think!
@rzeka
5 жыл бұрын
Dude I'm not even a programmer but this was really interesting! Kept my attention the entire time.
@joostvanrens
6 жыл бұрын
"Sorry I lost my.... What I was doing here for a second" Pretty much sums up Dan's way of working. :-p
@rysea9855
4 жыл бұрын
You Dutch?
@tastyl2356
4 жыл бұрын
and that's a good thing
@dropdown77
6 жыл бұрын
Curb Your Enthusiasm for Coding. Loving the intensity and your videos. Thanks Dan(LD)!
@tommulvey4752
6 жыл бұрын
Someday when I'm bored I'm going to recreate all these in python
@carterplasek498
6 жыл бұрын
I have done so to a couple, and be warned, pixel manipulation is not as fast.
@tommulvey4752
6 жыл бұрын
Carter Plasek I know, but it's still fun
@carterplasek498
6 жыл бұрын
Oh, of course, python is certain to grant a good time :D
@tommulvey4752
6 жыл бұрын
legobudgie it's okay! I'm just a freshman in University, and just learning as well:) I know python and c++ the best, and any java or js I know is from that hunk on screen
@simeondermaats
6 жыл бұрын
Everybody started out like that. Even all those geniusses like Dan or Alan Turing or whoever.
@Wander4P
2 жыл бұрын
I've known about Floyd-Steinberg Dithering, but never looked into the algorithm. I never knew it was so simple!
@JakeFace0
6 жыл бұрын
Really teaches me how much of a newB I am at programming
@dave6012
2 жыл бұрын
3 years later. Are you an oldG yet?
@ChristianSchmid
6 жыл бұрын
Hey Daniel, it's always impressive when you show us stuff in 30min, I use in Photoshop since 20 Years. Really love your channel and challenges and dithering ;-) .
@TheCodingTrain
6 жыл бұрын
Thank you!
@PressKribed
3 жыл бұрын
Your videos are not only comprehensive but also FUN. Thank you.
@davidwu1907
4 жыл бұрын
I like this guy. he is so enthusiastic and full of energy.
@atxorsatti
2 ай бұрын
i mean, the coding train, tsoding, and theprimagen are the gods of youtube programming
@sebastianrengelclaros3558
Жыл бұрын
Thanks for all the help, I was really struggling with this (this is part of my homework and I didn't catch the basics of the problem very much), but now I think I do understand a bit more. Thanks for all the work and effort you put in this.
@mariovelez578
2 жыл бұрын
Just made a cool application where I can convert any image into a LEGO mosaic, and it looks really cool when looking at a distance! Thanks for the coding challenge!
@xylonbeta4517
6 жыл бұрын
wow... so this is the power of computer science... impressive...
@em00k
4 жыл бұрын
Just a note on this, if translating to another language the "r = r + errR * 7/16.0" parts can give you values 255 which will cause artefacts. your rgbs need to be clamped so if 255 =255.
@MarcusHammarberg
Жыл бұрын
I love these videos and think it a great introduction to algorithmic thinking. Your inspiration is contagious! If anything I would love to see a refactoring exercise of each to see it improved in maintainability and quality. Thanks a lot.
@Gabirell
6 жыл бұрын
I love this guy. He is hilarious... And a programmer!? Xd
@elikay2101
6 жыл бұрын
I think it would be great if you did a challenge where you create an upscaling algorithm, similar to bilinear and linear upscaling you can find in programs like photoshop. There are some very advanced ones out there too that you can find in emulators for old pixel art games, although I don't know the names of them on the top of my head
@mateus44
6 жыл бұрын
like hq4x
@LifEsYouTubeChannel
6 жыл бұрын
When mum asks you "what are you doing?" you answer "Watching quantized kittens" and she's going to be like "wow... he's learning some kind of a quantum physics..." :D
@Skaggco
5 жыл бұрын
@LifE's KZitem Channel She can't prove that the cat is not alive if she can't see the screen
@FSFITA
5 жыл бұрын
@@Skaggco Quantized schrodinger
@AlexandrBorschchev
3 жыл бұрын
goddamn nerd
@Brahvim
3 жыл бұрын
@@FSFITA xDDDDDDDDD
@kyleyael9482
3 жыл бұрын
InstaBlaster
@Hafgandil
6 жыл бұрын
Wow.... this is actually helpful for my Shader Learning in GLSL :D Thank you!!!
@101abuse
2 жыл бұрын
I love those "algorithm" video's, where you are putting them into processing!
@CYON4D
4 жыл бұрын
Hey man, just wanted to say that your videos are simply awesome. Cheers!
@brocharognard
6 жыл бұрын
Wow i've just discover your channel and it's awesomly pedagogically good and intertaining
@gimeron-db
3 жыл бұрын
Интересно будет попробовать использовать фиксированные палитры или поменять распределение цветовой ошибки на картинке (распределить с другим соотношением или по большему количеству пикселей). PS: Классный канал, где программирование и творчество встречаются вместе.
@AJMansfield1
5 жыл бұрын
For another challenge, you could try using k-means to select an optimal set of palette colors, if you haven't done that in a video already.
@WyMustIGo
Жыл бұрын
k means sucks for photos, octree and median cut are better.
@sigmareaver680
5 жыл бұрын
For what it's worth, you can also explicitly make a float by appending 'f' to the number: 7/16f
@timofeyuvarov1267
Жыл бұрын
Thanks for the wonderful performance!
@slowdragon3023
3 жыл бұрын
I'm not great at coding but just found this channel and loving it. I feel like this guy would really like Return of the Obra Dinn since that's basically a game made with dithering.
@islandcave8738
2 жыл бұрын
Yes a function is what I was thinking for that very similar block of code and repeated 3 times. And just pass the variations as parameters.
@Wander4P
2 жыл бұрын
Really interesting how the video compression on the dithered cat @25:40 is completely lossless when viewed at the original 1080p scale. The pixel perfect black and white detail is completely preserved!
@phookadude
7 ай бұрын
I had an idea, take a dithered image and reverse it back into a continuous image but make it so that new image is much smaller than the original but still approximates the dithered image so it could be recreated from the smaller data set. A sort of lossy compression.
@Driftload
5 жыл бұрын
23:25 how I feel any time I finish writing in JavaScript and don't want to break it with missing closures again
@capriguelleri
2 жыл бұрын
You're an eccentric genius!
@VrIgHtEr
4 жыл бұрын
You need to keep a temporary row of floats to buffer error values for the next row (you only need one float for the pixel to the right, since it's always going to be the next one to be processed). A pixel is made up of its own value, as well as the errors of 4 other pixels. With each partial error you're adding you're doing "max(0, min(255, round(current_value + error)));" . Also, suppose a (for the sake of simplicity, assume grayscale) pixel has a value of 255, and its top left neighbour has an error of 16. This means that it would propagate 1 to the pixel in question, making the color (which can go from 0 to 255) into 256... this is a value that can't be stored in a value of type color, which only has 8 bits per color. Processing will do its clamping et voila: the error wasn't propagated at all. It looks like it's working. It's not working right though. You need to add all the errors and *then* convert back to a color. Converting to a color after adding each partial error results in lost information
@celivalg
6 жыл бұрын
for " r = round(r/255)*255", if you are in optimization, I think that an if statement is better, since you only do one test rather than a division, a test and a multiplication (the test come from the round function, i'm not sure how it's implemented in java, but the fastest way that I can think about comes with a test... and a few more number manipulations (I'd guess a truncation, a subtraction, a test and an addition)... In this case the optimization doesn't matter much since you only compute a relatively small image once on a powerful enough computer, but I had once a occasion where little optimizations like this helped a small computer do image processing much faster, reduced the time by a factor of at least 50... Or you could do it with 'r = r/128' if r is an integer (which I think it is) to get only one line, I think it should be a bit slower than the if statement, though I'm not sure, not too too familiar with assembly yet
@TheCodingTrain
6 жыл бұрын
Thanks for the feedback!
@naxaes7889
4 жыл бұрын
You have to consider when you do branching, the processor have to do a branch-predication. Basically, when it can take two different code branches, it'll guess which path the program will take and load code for one of the branches. This is so it can do optimizations as *out of order execution*, and *parallelism*. However, guessing wrong branch means that everything it has loaded and calculated in advance must be discarded, and the correct code has to be loaded. This is **slow**! So to know whether an if-statement is faster, you'll have to do what all optimization questions require; you have to measure it yourself!
@leoweigand
6 жыл бұрын
Loved the part where you posed for the thumbnail :D
@Max-yv2ws
6 жыл бұрын
24:51 when you reach the bitrate limit because of the noise
@f55665566
2 жыл бұрын
thanks for great tutuorial! I"m attending the 2022 Genuary challenge and found your dithering challenge! Trying to translate the code from processing to P5js.
@dappermink
6 жыл бұрын
All of your coding challenges are great, they are so much entertaining and give tons of ideas to beginners wondering what to code. Plus you really make them easy to follow..... but perhaps a little bit too easy. I definitely know you do that for the sake of clarity, but sometimes it makes your code choices really ugly and unseemly. I honestly think it would be really important for your viewers to see you working more on the code rather than the ouput only, even though it doesn't make it more impressive.
@TheCodingTrain
6 жыл бұрын
Thanks for this feedback, I completely understand what you mean and will consider this in the future.
@dappermink
6 жыл бұрын
Thanks a lot for your reply and even more for your consideration, I'll look forward to it!!
@absolutedogy346
6 жыл бұрын
I love watching his videos just for entertainment but I would love to see more practical approaches to some subject
@marcellomarianetti1770
6 жыл бұрын
Too Easy? AHAHAHAHAH
@kilianlindberg
4 жыл бұрын
Darn, I love these coding videos 🙌🙌 well done
@d_v_d1070
6 жыл бұрын
YIPPI! Processing3 is used = +1000 points
@rayredondo8160
6 жыл бұрын
22:00 Order of operations. errR gets multiplied by 7, and that float is divided by 16. It is all floating point in the end because the float comes first. I know this because I often get wrecked with integer division, but I know this is safe. Also, consider consolidating the definition of r and the addition on to one line.
@TheCodingTrain
6 жыл бұрын
Thanks for this correction!
@exxzxxe
2 жыл бұрын
Best channel on KZitem.
@electronicfeelings5832
6 жыл бұрын
Set that factor to 50, while using Greyscale. 50 shades of Gray!
@mrstanlez
2 жыл бұрын
...but for fast cycle is better to use only one loop, for index
@simonwillover4175
3 жыл бұрын
Oof! color pallete dithering? I didn't think of that genius artistry when I instantly came up with my own algorithm(s).
@Arrow6424
6 жыл бұрын
Great the way you explain your thinking! So extremely helpful as i'm a beginner
@gustaf_2611
5 жыл бұрын
1:24 lands perfectly on the nose
@gerdchen1000
5 жыл бұрын
„This is an integer, this is an integer. So it gives me an integer back“ But 255 divided by 4 is a float. I think it has to be 256 instead.
@revimfadli4666
5 жыл бұрын
Wouldn't it be a rounded-down division instead?
@gerdchen1000
5 жыл бұрын
Revi M Fadli sorry you‘re right. I disregarded the int cast.
@OG_CK2018
4 жыл бұрын
"Dithering Dithering Dithering" -- The coding train 2018
@R4ngeR4pidz
5 жыл бұрын
Again super interesting and learned a lot, would have liked to see an example on the whiteboard to see what the formula of 7/16, 3/16, 5/16 and 1/16 on those surrounding dots was doing though You can sort of imagine it, but visualizing it would have been cool
@some._earth
6 жыл бұрын
That awesome dithering effect at 14:44.
@MrRys
6 жыл бұрын
Lol... I just had a final exam from this topic
@pranav_r
6 жыл бұрын
I wish I had final exams on topics like this
@MrRys
6 жыл бұрын
it's not as exiting when it's only theory and pseudocode :D :D
@varunnagnure9643
3 жыл бұрын
@@MrRys right
@joeedh
6 жыл бұрын
If you're interested in image stippling, look up "poisson dart throwing" and "void-cluster method". A little trade secret, if you mean to apply relaxation to a stippled image, you might have to sharpen it a bit. Error diffusion will sharpen it a bit for you (that's partly why it's so popular), but other methods won't.
@TheCodingTrain
6 жыл бұрын
Thank you for these great tips!
@Bodyja
6 жыл бұрын
"The times you have to see duplicate code before extracting it into a function is 1" Hmmmm 🤔 23:00 Not gonna lie, I cried when I saw it xD
@oi_faen
6 жыл бұрын
this is nice for those who wants to show nice things on e-paper :)
@Alessandro-nq3tm
6 жыл бұрын
A question Dan: why do that in the draw function? It's better do the loop once in the setup. Right?
@TheCodingTrain
6 жыл бұрын
Yeah, since this is generating a static image it makes sense for it all to happen one in setup!
@xnick_uy
5 жыл бұрын
I had the same question. Now I would like to see how the dithering behaves as we slowly introduce slight variations in the palette thresholds and definitions (or also mixing the RGB channels).
@wing-it-right
6 жыл бұрын
I ran into a toolbar today, which is a plugin for atom to quickly setup a server and quickly create new P5 projects. Nothing special but kind of cool. I am not related to the project. just a quicktip - "p5js"or sth in atom package manager. And HEY I totally love your channel. :)
@keen_nocap
2 жыл бұрын
I think I learned more about coding concepts from this video than I did from my $70,000 master's degree education.
@erichomsy
3 жыл бұрын
i wanna smoke with this guy i feel like he'll talk your ear off then fall asleep eating a microwave burrito
@simonwillover4175
3 жыл бұрын
You did index ineffficiently ( 6:18 ). you should've done: int index = 0; for( int y = 0; y < kitten.width; y++ ){ for( int x = 0; x < kitten.height; x++ ){ /* drawiing */ index ++; } }
@esebrooks9411
6 жыл бұрын
My man Daniel looking like Luke Skywalker
@ZombieBrainz
6 жыл бұрын
Ese Brooks Luke or Chewbacca - I can’t make up my mind... ;-)
@superarcherg5320
3 жыл бұрын
quick tip: command + delete deletes an entire line
@ThankYouESM
4 жыл бұрын
Would also love to see the curvy lines version that sort of looks like a maze... better yet... that is a maze.
@TheBytesCode
6 жыл бұрын
Sitting here bored @ 12:30am... sees an upload from this mint fella! I love your attitude and enthusiasm, actually makes me interested in Hungary.
@TheBytesCode
6 жыл бұрын
Damn autocorrect, meant to say that it makes me interested in things I would otherwise not.
@TheMazyProduction
6 жыл бұрын
Checked your time zone you are off.
@TheBytesCode
6 жыл бұрын
Mazeyar Moeini I'm not in Hungary. That was autocorrect, I decided to leave it in there for the giggles.
@fairydragonbreath9192
6 жыл бұрын
I like processing. I've been playing with it for a bit, it's just that for some reason visual Studio doesn't like it. My apache server no prob. Thanks these videos are helping me get better.
@DashNothing
6 жыл бұрын
The beard is getting more and more majestic
@unoriginalpun
Жыл бұрын
In the p5 web editor, for some reason, even though you’re dithering it after displaying the original, it is showing the original dithered as well.
@wojtek4351
5 жыл бұрын
Dan is looking good with the beared
@mrmeowbeats7842
5 жыл бұрын
i feel like this would be a very handy method for increasing the resolution of an image (if you added pixels between each existing one to create a larger image)
@moritzheinzel815
4 жыл бұрын
there wouldnt be more detail tho
@Samisage
6 жыл бұрын
Keep up the good work! My coding club is now doing a lesson on Processing :)
@superarcherg5320
3 жыл бұрын
you murdered youtubes compression lol
@guinea_horn
6 жыл бұрын
Where do you get all these awesome ideas? I'd love to attempt something like this myself but I wouldn't know where to start
@skyslasher6267
2 жыл бұрын
I did this years ago in highschool for a project, i didnt know it was a thing that actually existed. I used processing also, thats so weird
@NatetheAceOfficial
6 жыл бұрын
The easiest way to achieve this effect? GameBoy Camera.
@YoBro230
6 жыл бұрын
I love seeing the quality dropping at 25:02 because of the fixed bitrate and the crazy detail :D
@jtkyber
6 жыл бұрын
I saw dithering as an option in a Skyrim ENB and always wondered what it did
@electron7373
2 жыл бұрын
Fascinating! Go Dan!
@ruchisheth9430
5 жыл бұрын
It would be interesting to have a video on index mode of photoshop in processing. To get custom colors with dithering types in an image.
@shayakoo1
6 жыл бұрын
Dayum! I always wanted to make these.
@artistpw
2 жыл бұрын
You should take a look at real etching, woodcuts and lithography images. You would not believe how amazing some of those images are.
@DaveHoskinsCG
6 жыл бұрын
Don't you need a blank image to start with when you start accumulating the error distribution? It looks like you're adding to the original image over and over again ( you can see it change quite a few times 24:48 ). It should look much nicer than this.
@aryamankejriwal5959
6 жыл бұрын
I can’t stop staring at the floating tuft of hair at the beginning...😅
@ScarlettNour
6 жыл бұрын
Hmmm, this reminds me... have you ever seen Raven Kwok's work for Karma Fields? The videoclip for Greatness and the one for Skyline are just beautiful. Would love to see you try something like those. Anyway, thanks for the one more coding challenge!
@brascoarts2634
2 жыл бұрын
Nerdiest guy I know ❤!
@Holobrine
5 жыл бұрын
You should make a quantize function that takes a number and a factor.
@rootbeer666
2 жыл бұрын
I'd do luminosity grayscale instead of color in the first step
@filipemecenas
2 жыл бұрын
Thanks im studing dither
@deanakers7394
3 жыл бұрын
what language is this?
@oniquits
3 ай бұрын
english 👍
@IrishJaguar
3 жыл бұрын
You: “pee-image” My brain: “pie-mage”
@simonwillover4175
3 жыл бұрын
You guys, the algorithm is NOT that complex. Here is the psuedo code: By the way, I love yor channel :) variable x = -0.25 for( every pixel on canvas ): { | p = corresponding pixel of image | convert p to a brightness value (black and white), from 0 to 1, with 0 being black, and 1 being white | increment x by p | // note: a negative chance is treated as false, meaning the if will fail | if( this random chance from x - 0.125 to + 0.125 ): { | | color in the square on the canvas white | | x = -0.25 | } | elsewise: { | | new x = prev x + 0.1; | | color in the square of the canvas black | } } Want you picture dithered in color? That's is very similar. I will **bold** the differences for you. Color dither psuedo code: variable x = -0.25 for( every pixel on canvas ): { | p = corresponding pixel of image | **set the color C as the normal color value of p** | **set the color I as the inverted color valud of p ( inverted means opposite brightness and hue )** | increment x by p | // note: a negative chance is treated as false, meaning the if will fail | if( this random chance from x - 0.125 to + 0.125 ): { | | color in the square on the canvas **with the color C** | | x = -0.25 | } | elsewise: { | | new x = prev x + 0.1; | | color in the square of the canvas **with the color I** | } } If you desire a more complex dithering the draws circles rather than individual pixels, here is its psuedo code: choose your own value, this is the radius of the circles : | radius = 5 constant area = radius * radius * pi; variable x = -0.25 create another 2d array, named "circle bois", with its width = floor( canvas width / radius ), and its height = floor( canvas height / radius ), every cell should be a boolean (1 or 0) (true or false) for( every pixel on canvas ): { | p = corresponding pixel of image | convert p to a brightness value (black and white), from 0 to 1, with 0 being black, and 1 being white | increment x by p | calculate n, as how many of the 8 neighboring pixel regions are already white, by: | | "cicle bois" at ( | | | x: floor( this pixel's x / radius ) + or - 1, | | | y: floor( this pixel's y / radius ) + or - 1 | | ) | // careful with that calculatio, as it has 8 steps and some must be skipped when we are at the edge of the drawing | // we just used "circle bois to count how many circles have already been drawn near by (roughly)" | | // note: a negative chance is treated as false, meaning the if will fail | if( this random chance ( from x - 0.125 to + 0.125 ) * ( 1 - n /8 ) / ( area ) ): { | | draw the circle, centered at this pixel | | color in the circle on the canvas white | | x = -0.25 | | we want to save to circle bos now, so | | | set "cicle bois" at ( | | | | x: floor( this pixel's x / radius ), | | | | y: floor( this pixel's y / radius ) | | | ) | | | equal to true | } | elsewise: { | | new x = prev x + 0.1; | | color in the square of the canvas black | } } I decided to make all of this in codepen while I was at it. Here is pixel by pixel dithering : codepen.io/simon-will-over/pen/dyNeQVZ And here is circle dithering : codepen.io/simon-will-over/pen/PoWexJy
@Daniel_Zhu_a6f
2 жыл бұрын
if you use a `map` pattern, you won't need all these stupid names and code repetitions. first you do quantization transform, that maps color values to pairs of (color, error) values, then you make a map on a sliding window of values. there is one and only right way to implement this: through `map` and generators. it is easy to write, read and parallelize.
@JosefdeJoanelli
2 жыл бұрын
Swap for loops for better perf
@tessler9710
5 жыл бұрын
So I just learned how to unHDify a picture and I can't resist the urge to implement it myself
@derpyllama1885
6 жыл бұрын
I like your beard
@lcastro
6 ай бұрын
Try coding a fillet crochet chart from a Black and white picture.😊
@e1211
4 жыл бұрын
I think it would get a better result if you used srgb to quantize the colors.
@Name-yf6xp
6 жыл бұрын
Could you use %amount of pixels in the index() function to get rid of out of bound errors, and make it rewind to the top? Btw yes, rip bitrate
@Bunny99s
6 жыл бұрын
No, this wouldn't make any sense for several reasons. First of all there is no point in having the error of a pixel on the right border to affect the pixel on the left border. The idea is to spread the error to the neighbor pixels and the left side is pretty far away from the right side ^^. Next problem is this would completely mess up those pixels. The algorithm relies on the fact that a processed / quantized pixel is never touched again. The error of the current pixel is only spread onto pixels that hasn't been processed yet. So the error adding is actually a preparation step before you quantize the pixel. The proper handling would be to not doing those steps when the x or y index is out of bounds. The easiest solution in his code would be to implement the bounds check inside the index method and when the index is out of bounds return "-1". Now we can simply check before each of those 4 steps if we got a valid index (index >= 0) int index = index(x + 1, y); if (index >= 0) { // ... } The index method could be changed into float index(int x, int y) { if (x < 0 || y < 0 || x >= kitten.width || y >= kitten.height) return -1; return x + y * kitten.width; }
@numero7mojeangering
5 жыл бұрын
you could use PVectors to store the RGB colors
@aayushsaini9363
6 жыл бұрын
Yes I am newB in p5. Not R nor G but only and only B
Пікірлер: 354