-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0a78839
commit 328bd04
Showing
64 changed files
with
4,011 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# RIP | ||
|
||
RIP is a library for complex image processing. | ||
|
||
## License | ||
|
||
GPLv3 | ||
|
||
## How to use RIP? | ||
|
||
Package in your `dub.json`: | ||
```d | ||
{ | ||
"dependencies": { | ||
"rip": "~>0.0.1" | ||
} | ||
} | ||
``` | ||
## Dependencies | ||
|
||
RIP needs dlib library for loading jpeg/png/bmp/tga files. | ||
WARNING: image can be saved ONLY in ppm/pam/png formats. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"name": "rip", | ||
"description": "Raster and Image processor", | ||
"copyright": "Copyright © 2016, Oleg Baharew, Roman Vlasov", | ||
"license": "GPL-3.0", | ||
"authors": ["Oleg Baharev (aka aquaratixc)", "Roman Vlasov"], | ||
"dependencies": { | ||
"dlib": { | ||
"version" : "*" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
module rip.analysis.histogram; | ||
|
||
private { | ||
import std.algorithm; | ||
import std.range; | ||
import std.math; | ||
|
||
import rip.concepts.color; | ||
import rip.concepts.surface; | ||
import rip.concepts.channel; | ||
import rip.concepts.ranges : toSurface; | ||
} | ||
|
||
struct Histogram { | ||
uint[] data; | ||
|
||
const Channel channel; | ||
|
||
alias data this; | ||
|
||
this(Channel channel) { | ||
this.channel = channel; | ||
data = new uint[channel.getRangeSize!uint()]; | ||
} | ||
} | ||
|
||
Histogram takeHistogram(Range)(in Range pixelRange, Channel channel) | ||
//Проверка типа на InputRange | ||
//if(InputRange!Range) | ||
{ | ||
auto histogram = Histogram(channel); | ||
|
||
pixelRange | ||
.getPixels() | ||
.each!( | ||
(color) => histogram[ channel.getIndex(color) ]++ | ||
); | ||
|
||
return histogram; | ||
} | ||
|
||
//std.algorithm.max не приспособлен для диапазонов | ||
//TODO: убрать это отсюда. Ну позязя :p | ||
T maxValue(T)(T[] args...) { | ||
T max = args[0]; | ||
|
||
foreach(value; args) { | ||
if(value > max) | ||
max = value; | ||
} | ||
|
||
return max; | ||
} | ||
|
||
Surface drawHistogram( Histogram histogram, | ||
RGBColor background = new RGBColor(255, 255, 255), | ||
RGBColor pencil = new RGBColor(0, 0, 0)) { | ||
uint width = histogram.channel.getRangeSize!uint; | ||
uint height = cast(uint) | ||
(maxValue(histogram.data) / histogram.channel.getRangeSize!float); | ||
|
||
auto surface = new Surface(width, height); | ||
|
||
foreach(i; 0..width) { | ||
foreach(j; 0..height) { | ||
if(j <= histogram[i] / histogram.channel.getRangeSize!float()) { | ||
surface[i, height - j - 1] = pencil; | ||
} | ||
else { | ||
surface[i, height - j - 1] = background; | ||
} | ||
} | ||
} | ||
|
||
return surface; | ||
} | ||
|
||
auto equalizeHistogram(Histogram histogram) { | ||
Histogram equalizedHistogram = histogram; | ||
|
||
uint pixelsNumber = histogram.data.reduce!"a + b"; | ||
|
||
auto probability = histogram | ||
.data | ||
.map!(( float a) => a / pixelsNumber) | ||
.array; | ||
|
||
int i = 1; | ||
foreach(ref el; probability[1..$-1]) { | ||
el += probability[i-1]; | ||
i++; | ||
} | ||
|
||
uint size = histogram.channel.getRangeSize!uint; | ||
|
||
equalizedHistogram = probability.map!(a => cast(uint)(a * size)).array; | ||
return equalizedHistogram; | ||
} | ||
|
||
Surface appearHistogramToSurface(Histogram histogram, Surface sur) { | ||
import rip.concepts; | ||
|
||
auto channel = histogram.channel; | ||
|
||
auto getNewColor(in RGBColor color) { | ||
return channel.injectValue(color, channel.getValue(color)); | ||
} | ||
|
||
return sur | ||
//функция ниже отзеркаливает картинку по диагонали | ||
.createFences(1,1) | ||
.map!(a => a.front) | ||
.map!getNewColor | ||
//функция ниже отзеркаливает картинку по диагонали | ||
.toSurface(sur.getWidth!size_t, sur.getHeight!size_t); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module rip.analysis; | ||
|
||
public{ | ||
import rip.analysis.histogram; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
module rip.concepts.channel; | ||
//пересмотреть концепт каналов, и в случае введения в проект, | ||
//перенести его в concepts. | ||
|
||
private { | ||
import std.algorithm; | ||
import std.math; | ||
|
||
import rip.concepts.color; | ||
} | ||
|
||
class Channel { | ||
float[2] range; | ||
uint function(in RGBColor color) getValue; | ||
|
||
RGBColor function( in RGBColor color, | ||
in float value) injectValue; | ||
|
||
this( float rangeMin, float rangeMax, | ||
uint function(in RGBColor color) func, | ||
RGBColor function(in RGBColor color, in float value) colorFunc){ | ||
|
||
range[0] = rangeMin; | ||
range[1] = rangeMax; | ||
getValue = func; | ||
injectValue = colorFunc; | ||
} | ||
|
||
T getRangeSize(T)() const { | ||
return cast(T)round(range[1] - range[0] + 1); | ||
} | ||
} | ||
|
||
enum DefaultChannels { | ||
|
||
Red = new Channel( | ||
0.0f, 255.0f, | ||
(in color) => color.red!int, | ||
(in color, in value) => new RGBColor( | ||
value, | ||
color.green!ubyte, | ||
color.blue!ubyte) | ||
), | ||
|
||
Green = new Channel( | ||
0.0f, 255.0f, | ||
(in color) => color.green!int, | ||
(in color, in value) => new RGBColor( | ||
color.red!ubyte, | ||
value, | ||
color.blue!ubyte) | ||
), | ||
|
||
Blue = new Channel( | ||
0.0f, 255.0f, | ||
(in color) => color.blue!int, | ||
(in color, in value) => new RGBColor( | ||
color.red!ubyte, | ||
color.green!ubyte, | ||
value) | ||
), | ||
|
||
Grayscale = new Channel( | ||
0.0f, 255.0f, | ||
//так-как для построении гистограммы требуется черно-белое изображение, | ||
//достаточно узнать только значение одного из каналов | ||
(in color) => color.blue!int, | ||
(in color, in value) => new RGBColor( | ||
value, value, value) | ||
) | ||
} |
Oops, something went wrong.