├── Readme.md ├── result └── 1.mp4 ├── video └── 1.mp4 └── glsl └── saturation.glsl /Readme.md: -------------------------------------------------------------------------------- 1 | # AI-video-enhance 2 | This repository is a set of open-source, high-quality real-time video enhance algorithms that can be implemented in any programming language. 3 | 4 | # How to use (GLSL / MPV) 5 | 1. install MPV 6 | 2. Download the .glsl shader files here 7 | 3. Copy the .glsl files to %AppData%\mpv\shaders for Windows 8 | 9 | 10 | -------------------------------------------------------------------------------- /result/1.mp4: -------------------------------------------------------------------------------- 1 | //Anime4K v3.1 GLSL 2 | 3 | // This is free and unencumbered software released into the public domain. 4 | 5 | // Anyone is free to copy, modify, publish, use, compile, sell, or 6 | // distribute this software, either in source code form or as a compiled 7 | // binary, for any purpose, commercial or non-commercial, and by any 8 | // means. 9 | 10 | // In jurisdictions that recognize copyright laws, the author or authors 11 | // of this software dedicate any and all copyright interest in the 12 | // software to the public domain. We make this dedication for the benefit 13 | // of the public at large and to the detriment of our heirs and 14 | // successors. We intend this dedication to be an overt act of 15 | // relinquishment in perpetuity of all present and future rights to this 16 | // software under copyright law. 17 | 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | // OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | // For more information, please refer to 27 | 28 | //!DESC Anime4K-v3.1-DarkLines-Kernel(X) 29 | //!HOOK NATIVE 30 | //!BIND HOOKED 31 | 32 | vec3 rgb2hsv(vec3 c) 33 | { 34 | vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 35 | vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); 36 | vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); 37 | 38 | float d = q.x - min(q.w, q.y); 39 | float e = 1.0e-10; 40 | return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); 41 | } 42 | 43 | vec3 hsv2rgb(vec3 c) 44 | { 45 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 46 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); 47 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); 48 | } 49 | 50 | vec3 sat(vec3 img) 51 | { 52 | img = img / 255.0; 53 | float Increment = 0.03; 54 | float img_min = min(img.r, min(img.g, img.b)); 55 | float img_max = max(img.r, max(img.g, img.b)); 56 | 57 | float Delta = (img_max - img_min); 58 | float value = (img_max + img_min); 59 | 60 | float L = value/2.0; 61 | 62 | float mask_1 = 0.0; 63 | if(L < 0.5) { 64 | mask_1 = 1.0; 65 | } else { 66 | mask_1 = 0.0; 67 | } 68 | 69 | float s1 = Delta / (value + 0.001); 70 | float s2 = Delta / (2.0 - value + 0.001); 71 | float s = s1*mask_1 + s2*(1.0 - mask_1); 72 | 73 | 74 | if(Increment >= 0.0) { 75 | float temp = Increment + s; 76 | float mask_2 = 0.0; 77 | if(temp > 1.0){ 78 | mask_2 = 1.0; 79 | } else { 80 | mask_2 = 0.0; 81 | } 82 | float alpha_1 = s; 83 | float alpha_2 = s*0.0 + 1.0 - Increment; 84 | float alpha = alpha_1*mask_2 + alpha_2*(1.0 - mask_2); 85 | alpha = 1.0/(alpha + 0.001) - 1.0; 86 | img.r = img.r + (img.r - L) * alpha; 87 | img.g = img.g + (img.g - L) * alpha; 88 | img.b = img.b + (img.b - L) * alpha; 89 | } else { 90 | float alpha = Increment; 91 | img.r = img.r + (img.r - L) * alpha; 92 | img.g = img.g + (img.g - L) * alpha; 93 | img.b = img.b + (img.b - L) * alpha; 94 | } 95 | 96 | 97 | vec3 img_out = img; 98 | float mask_r_1 = 0.0; 99 | float mask_r_2 = 0.0; 100 | float mask_g_1 = 0.0; 101 | float mask_g_2 = 0.0; 102 | float mask_b_1 = 0.0; 103 | float mask_b_2 = 0.0; 104 | 105 | if(img_out.r < 0.0){ 106 | mask_r_1 = 1.0; 107 | } else { 108 | mask_r_1 = 0.0; 109 | } 110 | if(img_out.r > 1.0){ 111 | mask_r_2 = 1.0; 112 | } else { 113 | mask_r_2 = 0.0; 114 | } 115 | 116 | if(img_out.g < 0.0){ 117 | mask_g_1 = 1.0; 118 | } else { 119 | mask_g_1 = 0.0; 120 | } 121 | if(img_out.g > 1.0){ 122 | mask_g_2 = 1.0; 123 | } else { 124 | mask_g_2 = 0.0; 125 | } 126 | 127 | 128 | if(img_out.b < 0.0){ 129 | mask_b_1 = 1.0; 130 | } else { 131 | mask_b_1 = 0.0; 132 | } 133 | if(img_out.b > 1.0){ 134 | mask_b_2 = 1.0; 135 | } else { 136 | mask_b_2 = 0.0; 137 | } 138 | 139 | 140 | //img_out = img_out * (1.0-mask_r_1, 1.0-mask_g_1, 1.0-mask_b_1); 141 | img_out.r = img_out.r*(1.0-mask_r_1); 142 | img_out.g = img_out.g*(1.0-mask_g_1); 143 | img_out.b = img_out.b*(1.0-mask_b_1); 144 | //img_out = img_out * (1.0-mask_r_2, 1.0-mask_g_2, 1.0-mask_b_2) + (mask_r_2, mask_g_2, mask_b_2); 145 | img_out.r = img_out.r*(1.0-mask_r_2); 146 | img_out.g = img_out.g*(1.0-mask_g_2); 147 | img_out.b = img_out.b*(1.0-mask_b_2); 148 | img_out += (mask_r_2, mask_g_2, mask_b_2); 149 | img_out = img_out * 255.0; 150 | 151 | return img_out; 152 | } 153 | 154 | #define L_tex HOOKED_tex 155 | 156 | #define SIGMA 1 157 | 158 | float gaussian(float x, float s, float m) { 159 | return (1 / (s * sqrt(2 * 3.14159))) * exp(-0.5 * pow(abs(x - m) / s, 2.0)); 160 | } 161 | 162 | float lumGaussian(vec2 pos, vec2 d) { 163 | float s = SIGMA * HOOKED_size.y / 1080; 164 | float kernel_size = s * 2 + 1; 165 | 166 | float g = (L_tex(pos).x) * gaussian(0, s, 0); 167 | float gn = gaussian(0, s, 0); 168 | 169 | g += (L_tex(pos - d).x + L_tex(pos + d).x) * gaussian(1, s, 0); 170 | gn += gaussian(1, s, 0) * 2; 171 | 172 | for (int i=2; i 27 | 28 | //!DESC Anime4K-v3.1-DarkLines-Kernel(X) 29 | //!HOOK NATIVE 30 | //!BIND HOOKED 31 | 32 | vec3 rgb2hsv(vec3 c) 33 | { 34 | vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 35 | vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); 36 | vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); 37 | 38 | float d = q.x - min(q.w, q.y); 39 | float e = 1.0e-10; 40 | return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); 41 | } 42 | 43 | vec3 hsv2rgb(vec3 c) 44 | { 45 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 46 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); 47 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); 48 | } 49 | 50 | vec3 sat(vec3 img) 51 | { 52 | img = img / 255.0; 53 | float Increment = 0.03; 54 | float img_min = min(img.r, min(img.g, img.b)); 55 | float img_max = max(img.r, max(img.g, img.b)); 56 | 57 | float Delta = (img_max - img_min); 58 | float value = (img_max + img_min); 59 | 60 | float L = value/2.0; 61 | 62 | float mask_1 = 0.0; 63 | if(L < 0.5) { 64 | mask_1 = 1.0; 65 | } else { 66 | mask_1 = 0.0; 67 | } 68 | 69 | float s1 = Delta / (value + 0.001); 70 | float s2 = Delta / (2.0 - value + 0.001); 71 | float s = s1*mask_1 + s2*(1.0 - mask_1); 72 | 73 | 74 | if(Increment >= 0.0) { 75 | float temp = Increment + s; 76 | float mask_2 = 0.0; 77 | if(temp > 1.0){ 78 | mask_2 = 1.0; 79 | } else { 80 | mask_2 = 0.0; 81 | } 82 | float alpha_1 = s; 83 | float alpha_2 = s*0.0 + 1.0 - Increment; 84 | float alpha = alpha_1*mask_2 + alpha_2*(1.0 - mask_2); 85 | alpha = 1.0/(alpha + 0.001) - 1.0; 86 | img.r = img.r + (img.r - L) * alpha; 87 | img.g = img.g + (img.g - L) * alpha; 88 | img.b = img.b + (img.b - L) * alpha; 89 | } else { 90 | float alpha = Increment; 91 | img.r = img.r + (img.r - L) * alpha; 92 | img.g = img.g + (img.g - L) * alpha; 93 | img.b = img.b + (img.b - L) * alpha; 94 | } 95 | 96 | 97 | vec3 img_out = img; 98 | float mask_r_1 = 0.0; 99 | float mask_r_2 = 0.0; 100 | float mask_g_1 = 0.0; 101 | float mask_g_2 = 0.0; 102 | float mask_b_1 = 0.0; 103 | float mask_b_2 = 0.0; 104 | 105 | if(img_out.r < 0.0){ 106 | mask_r_1 = 1.0; 107 | } else { 108 | mask_r_1 = 0.0; 109 | } 110 | if(img_out.r > 1.0){ 111 | mask_r_2 = 1.0; 112 | } else { 113 | mask_r_2 = 0.0; 114 | } 115 | 116 | if(img_out.g < 0.0){ 117 | mask_g_1 = 1.0; 118 | } else { 119 | mask_g_1 = 0.0; 120 | } 121 | if(img_out.g > 1.0){ 122 | mask_g_2 = 1.0; 123 | } else { 124 | mask_g_2 = 0.0; 125 | } 126 | 127 | 128 | if(img_out.b < 0.0){ 129 | mask_b_1 = 1.0; 130 | } else { 131 | mask_b_1 = 0.0; 132 | } 133 | if(img_out.b > 1.0){ 134 | mask_b_2 = 1.0; 135 | } else { 136 | mask_b_2 = 0.0; 137 | } 138 | 139 | 140 | //img_out = img_out * (1.0-mask_r_1, 1.0-mask_g_1, 1.0-mask_b_1); 141 | img_out.r = img_out.r*(1.0-mask_r_1); 142 | img_out.g = img_out.g*(1.0-mask_g_1); 143 | img_out.b = img_out.b*(1.0-mask_b_1); 144 | //img_out = img_out * (1.0-mask_r_2, 1.0-mask_g_2, 1.0-mask_b_2) + (mask_r_2, mask_g_2, mask_b_2); 145 | img_out.r = img_out.r*(1.0-mask_r_2); 146 | img_out.g = img_out.g*(1.0-mask_g_2); 147 | img_out.b = img_out.b*(1.0-mask_b_2); 148 | img_out += (mask_r_2, mask_g_2, mask_b_2); 149 | img_out = img_out * 255.0; 150 | 151 | return img_out; 152 | } 153 | 154 | #define L_tex HOOKED_tex 155 | 156 | #define SIGMA 1 157 | 158 | float gaussian(float x, float s, float m) { 159 | return (1 / (s * sqrt(2 * 3.14159))) * exp(-0.5 * pow(abs(x - m) / s, 2.0)); 160 | } 161 | 162 | float lumGaussian(vec2 pos, vec2 d) { 163 | float s = SIGMA * HOOKED_size.y / 1080; 164 | float kernel_size = s * 2 + 1; 165 | 166 | float g = (L_tex(pos).x) * gaussian(0, s, 0); 167 | float gn = gaussian(0, s, 0); 168 | 169 | g += (L_tex(pos - d).x + L_tex(pos + d).x) * gaussian(1, s, 0); 170 | gn += gaussian(1, s, 0) * 2; 171 | 172 | for (int i=2; i 27 | 28 | //!DESC Anime4K-v3.1-DarkLines-Kernel(X) 29 | //!HOOK NATIVE 30 | //!BIND HOOKED 31 | 32 | vec3 rgb2hsv(vec3 c) 33 | { 34 | vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 35 | vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); 36 | vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); 37 | 38 | float d = q.x - min(q.w, q.y); 39 | float e = 1.0e-10; 40 | return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); 41 | } 42 | 43 | vec3 hsv2rgb(vec3 c) 44 | { 45 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 46 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); 47 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); 48 | } 49 | 50 | vec3 sat(vec3 img) 51 | { 52 | img = img / 255.0; 53 | float Increment = 0.03; 54 | float img_min = min(img.r, min(img.g, img.b)); 55 | float img_max = max(img.r, max(img.g, img.b)); 56 | 57 | float Delta = (img_max - img_min); 58 | float value = (img_max + img_min); 59 | 60 | float L = value/2.0; 61 | 62 | float mask_1 = 0.0; 63 | if(L < 0.5) { 64 | mask_1 = 1.0; 65 | } else { 66 | mask_1 = 0.0; 67 | } 68 | 69 | float s1 = Delta / (value + 0.001); 70 | float s2 = Delta / (2.0 - value + 0.001); 71 | float s = s1*mask_1 + s2*(1.0 - mask_1); 72 | 73 | 74 | if(Increment >= 0.0) { 75 | float temp = Increment + s; 76 | float mask_2 = 0.0; 77 | if(temp > 1.0){ 78 | mask_2 = 1.0; 79 | } else { 80 | mask_2 = 0.0; 81 | } 82 | float alpha_1 = s; 83 | float alpha_2 = s*0.0 + 1.0 - Increment; 84 | float alpha = alpha_1*mask_2 + alpha_2*(1.0 - mask_2); 85 | alpha = 1.0/(alpha + 0.001) - 1.0; 86 | img.r = img.r + (img.r - L) * alpha; 87 | img.g = img.g + (img.g - L) * alpha; 88 | img.b = img.b + (img.b - L) * alpha; 89 | } else { 90 | float alpha = Increment; 91 | img.r = img.r + (img.r - L) * alpha; 92 | img.g = img.g + (img.g - L) * alpha; 93 | img.b = img.b + (img.b - L) * alpha; 94 | } 95 | 96 | 97 | vec3 img_out = img; 98 | float mask_r_1 = 0.0; 99 | float mask_r_2 = 0.0; 100 | float mask_g_1 = 0.0; 101 | float mask_g_2 = 0.0; 102 | float mask_b_1 = 0.0; 103 | float mask_b_2 = 0.0; 104 | 105 | if(img_out.r < 0.0){ 106 | mask_r_1 = 1.0; 107 | } else { 108 | mask_r_1 = 0.0; 109 | } 110 | if(img_out.r > 1.0){ 111 | mask_r_2 = 1.0; 112 | } else { 113 | mask_r_2 = 0.0; 114 | } 115 | 116 | if(img_out.g < 0.0){ 117 | mask_g_1 = 1.0; 118 | } else { 119 | mask_g_1 = 0.0; 120 | } 121 | if(img_out.g > 1.0){ 122 | mask_g_2 = 1.0; 123 | } else { 124 | mask_g_2 = 0.0; 125 | } 126 | 127 | 128 | if(img_out.b < 0.0){ 129 | mask_b_1 = 1.0; 130 | } else { 131 | mask_b_1 = 0.0; 132 | } 133 | if(img_out.b > 1.0){ 134 | mask_b_2 = 1.0; 135 | } else { 136 | mask_b_2 = 0.0; 137 | } 138 | 139 | 140 | //img_out = img_out * (1.0-mask_r_1, 1.0-mask_g_1, 1.0-mask_b_1); 141 | img_out.r = img_out.r*(1.0-mask_r_1); 142 | img_out.g = img_out.g*(1.0-mask_g_1); 143 | img_out.b = img_out.b*(1.0-mask_b_1); 144 | //img_out = img_out * (1.0-mask_r_2, 1.0-mask_g_2, 1.0-mask_b_2) + (mask_r_2, mask_g_2, mask_b_2); 145 | img_out.r = img_out.r*(1.0-mask_r_2); 146 | img_out.g = img_out.g*(1.0-mask_g_2); 147 | img_out.b = img_out.b*(1.0-mask_b_2); 148 | img_out += (mask_r_2, mask_g_2, mask_b_2); 149 | img_out = img_out * 255.0; 150 | 151 | return img_out; 152 | } 153 | 154 | #define L_tex HOOKED_tex 155 | 156 | #define SIGMA 1 157 | 158 | float gaussian(float x, float s, float m) { 159 | return (1 / (s * sqrt(2 * 3.14159))) * exp(-0.5 * pow(abs(x - m) / s, 2.0)); 160 | } 161 | 162 | float lumGaussian(vec2 pos, vec2 d) { 163 | float s = SIGMA * HOOKED_size.y / 1080; 164 | float kernel_size = s * 2 + 1; 165 | 166 | float g = (L_tex(pos).x) * gaussian(0, s, 0); 167 | float gn = gaussian(0, s, 0); 168 | 169 | g += (L_tex(pos - d).x + L_tex(pos + d).x) * gaussian(1, s, 0); 170 | gn += gaussian(1, s, 0) * 2; 171 | 172 | for (int i=2; i