I'm trying to implement/convert the daltonize algorithm for correcting images for colour-blind people into ruby.
There are two primary reference implementations written in javascript and python + other implementations in languages/environments I'm not familiar with.
I have virtually no experience with image processing, let alone with VIPS / ruby-vips. I'm wondering how to make the first steps. The documentation seems primarily in C/C++ and very little on the ruby side. It's also extremely detailed. I'm not even sure which basic operations to use. Looks like the lin function is a good starting point, but I'm not exactly sure how to apply it.
Anybody with some VIPS experience can probably work out the entire algorithm in a few minutes. I wonder if anybody can give me some pointers on where to start. Specifically:
How to access a single (R/G/B) element?
Are there better approaches based on the daltonize implementations?
(note This was a very old answer and described ruby-vips as of two major versions ago. I've updated it for the 2.0.16 gem, the current version in November 2019)
There is complete documentation here:
https://rubydoc.info/gems/ruby-vips
The Vips section has a tutorial-style introduction:
https://rubydoc.info/gems/ruby-vips/Vips
For example:
require 'vips'
if ARGV.length < 2
raise "usage: #{$PROGRAM_NAME}: input-file output-file"
end
im = Vips::Image.new_from_file ARGV[0], access: :sequential
im *= [1, 2, 1]
mask = Vips::Image.new_from_array [
[-1, -1, -1],
[-1, 16, -1],
[-1, -1, -1]
], 8
im = im.conv mask, precision: :integer
im.write_to_file ARGV[1]
This opens an image in streaming mode, multiplies the middle band (green) by two, sharpens the image with an integer convolution, and writes the result back. You can run it like this:
./example.rb x.jpg y.ppm
There's a full "daltonize" example in the ruby-vips repo:
https://github.com/libvips/ruby-vips/blob/master/example/daltonize8.rb
For newcomers: ruby-vips has wiki: https://github.com/jcupitt/ruby-vips/wiki with 'Examples' and 'Basic concepts' pages in it. They show the basics of ruby-vips usage.
Also, feel free to add your own use cases there, like #YoavAner did (Daltonize example).
Related
I'm working on the C++ version of Matt Zucker's Page dewarping. So far everything works fine, but I have a problem with optimization. In line 748 of Github repo Matt uses optimize function from Scipy. My C++ equivalent is find_min_bobyqa from dlib.net. The code is:
auto f = [&](const column_vector& ppts) { return objective( dstpoints, ppts, keypoint_index); };
dlib::find_min_bobyqa(f,
params,
2 * params.nr() + 1, // npt - number of interpolation points: x.size() + 2 <= npt && npt <= (x.size()+1)*(x.size()+2)/2
dlib::uniform_matrix<double>(params.nr(), 1, -2), // lower bound constraint
dlib::uniform_matrix<double>(params.nr(), 1, 2), // upper bound constraint
1, // initial trust region radius
1e-5, // stopping trust region radius
4000 // max number of objective function evaluations
);
In my concrete example params is a dlib::column_vector with double values and length = 189. Every element of params is less than 2.0 and greater than -2.0. Function objective() returns double value and "alone" it works properly because I get the same value as in the Python version. But after running fin_min_bobyqa function I usually get the message:
Terminate called after throwing an instance of 'dlib:bobyqa_failure', return from BOBYQA because the objective function has been called max_f_evals times.
I set max_f_evals to quite big value to see if it optimizes at all, but it doesn't. I did some tweaking with parameters but without good results. How should I set the parameters of find_min_bobyqa to get the right solution?
I am very interested in this issue as well. Zucker's work, with very minor tweaks, is ideal for straightening sheet music images, and I was looking for ways to implement it in a mobile platform when I came across your question.
My research so far suggests that BOBYQA is not the equivalent of Powell's method in scipy. BOBYQA is constrained, and the one in scipy is not.
See these links for more information, and a possible way to compile the right supporting library - I would try UOBYQA or NEWUOA.
https://github.com/jacobwilliams/PowellOpt
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html#rdd2e1855725e-3
(See the Notes section)
EDIT: see C version here:
https://github.com/emmt/Algorithms/tree/master/newuoa
I wanted to post this as a comment, but I don't have enough points for that.
I am very interested in your progress. If you're willing, please keep me posted.
I finally solved this problem. I used PRAXIS library, because it doesn't need derivative information and is fast.
I modified the code a little to my needs and now it is faster around few seconds than original version written in Python.
still learning about Ruby + Sketchup!
Today,I would like to add a measurement (good english word ?) as I can do manually with the 'cotation' (french version) tool when I click to point then drag the measure text.
Can't find that in the docs to do with Ruby and API ...
Thanks for your help
You are probably looking for the Sketchup::Entities::add_dimension_linear method.
http://ruby.sketchup.com/Sketchup/Entities.html#add_dimension_linear-instance_method
Assuming a and b below are edges
voffset = [-20, 0, 0]
Sketchup.active_model.entities.add_dimension_linear(a.start, b.start, voffset)
The value of voffset controls not just how far offset the dimension is, but also the axis along which the measurement is made. You may need to experiment with different values to get a feeling for how that determination is done. As with many things in SketchUp, it often guesses (or 'infers') at what you want.
I am trying to learn Julia by repeating some of the easy ProjectEuler problems in Julia. Everything has been really smooth so far, up until I encountered this frustrating problem. I spent some time debugging my code, and here's what I found:
(Hopefully I'm not missing something really stupid here)
function is_abundant(n::Int) #just a function
return prod(map(x->int((x[1]^(x[2]+1)-1)/(x[1]-1)),factor(n))) > 2 * n
end
abundants=[12] #there should be a better way to initialize an Array
for i=13:28120
if is_abundant(i)
push!(abundants,i)
end
end
le=abundants; #The following lines are the problems
ri=abundants;
d=length(abundants)
println(d)
pop!(le)
shift!(ri)
println(le==ri, " ", endof(ri), " ", endof(abundants))
The output I get is:
6964
true 6962 6962
which means that Julia has changed all three sets of le , ri and abundants with each of pop! and shift! commands. I was able to work around this bug/problem by using a dumb extra identity mapping:
le=map(x->x,abundants)
ri=map(x->x,abundants)
Now the output would change to what I initially expected:
6964
false 6963 6964
My question is, if this is not a bug, why is Julia keeping an equivalence relation between le , ri and abundants sets in the first place? Also, can anyone reproduce this behaviour? I am using Julia "Version 0.3.0-rc3+14 (2014-08-13 16:01 UTC)" on Ubuntu 14.04.
le and ri both point to the same list that abundants points to, so this is expected behavior - they are all operating on the same memory. This part of the manual might help you understand. Or possibly the MATLAB differences section, as it is different in MATLAB (but most other languages are like Julia).
For
abundants=[12] #there should be a better way to initialize an Array
how about
abundants = {} # Vector of anything
or
abundants = Int[] # Vector of ints
and instead of your map(x->x,...), you can just use copy.
I'm not a programmer, even amateur, I just wanted a program that would change PSP screen (whole) color as fast as possible infinitely. I made something:
rdupa = Image.load("red.png")
gdupa = Image.load("green.png")
bdupa = Image.load("blue.png")
screen:clear()
while true do
screen:blit(0, 0, rdupa, false)
screen:clear()
screen:blit(0, 0, gdupa, false)
screen:clear()
screen:blit(0, 0, bdupa, false)
screen:clear()
end
Using Google, but that doesn't work. What did I do wrong (I have *.png images in the same folder as script)? Ready script would be seen veeeeeeery nicely.
I'm not sure about your environment but I'd guess it's most likely unable to update its main window or whatever as it's essentially stuck executing the Lua code snipped (unless that's executed in a separate thread).
Lua is a small and concise programming language and provides only few core functions (see this list).
Lua does not provide any functions to work with screen and images by default, so without knowing what library/framework are you using, there is little we can do to help.
For this answer, I'm operating under the assumption that you're using Lua Player (consider adding a luaplayer tag?). From what I can see in the documentation, you should be using
screen.flip()
instead of
screen:clear()
whenever you want to update the screen. Unfortunately, I do not have CFW on my PSP, so I cannot test this myself.
To be honest, I wouldn't even consider using images.
something like this would do :)
(This is using PGELua but can easily be adapted for LuaPlayer)
while pge.running() do
color = pge.gfx.createcolor(pge.math.rand(255),pge.math.rand(255),pge.math.rand(255))
pge.gfx.startdrawing()
pge.gfx.drawrect(0,0,480,272,color)
pge.gfx.enddrawing()
pge.gfx.swapbuffers()
end
if you want defined colours, maybe something like.
red = pge.gfx.createcolor(255,0,0)
gre = pge.gfx.createcolor(0,255,0)
blu = pge.gfx.createcolor(0,0,255)
loop = 1
while pge.running() do
pge.gfx.startdrawing()
if loop==1 then
pge.gfx.drawrect(0,0,480,272,red)
elseif loop==2 then
pge.gfx.drawrect(0,0,480,272,gre)
elseif loop==3 then
pge.gfx.drawrect(0,0,480,272,blu)
end
loop=loop+1
if loop>4 then
loop=1
end
pge.gfx.enddrawing()
pge.gfx.swapbuffers()
end
For an offline-capable smartphone app, I'm creating a one-way text sync for Xml files. I'd like my server to send the delta/difference (e.g. a GNU diff-patch) to the target device.
This is the plan:
Time = 0
Server: has version_1 of Xml file (~800 kiB)
Client: has version_1 of Xml file (~800 kiB)
Time = 1
Server: has version_1 and version_2 of Xml file (each ~800 kiB)
computes delta of these versions (=patch) (~10 kiB)
sends patch to Client (~10 kiB transferred)
Client: computes version_2 from version_1 and patch <= this is the problem =>
Is there a Ruby library that can do this last step to apply a text patch to files/strings? The patch can be formatted as required by the library.
Thanks for your help!
(I'm using the Rhodes Cross-Platform Framework, which uses Ruby as programming language.)
Your first task is to choose a patch format. The hardest format for humans to read (IMHO) turns out to be the easiest format for software to apply: the ed(1) script. You can start off with a simple /usr/bin/diff -e old.xml new.xml to generate the patches; diff(1) will produce line-oriented patches but that should be fine to start with. The ed format looks like this:
36a
<tr><td class="eg" style="background: #182349;"> </td><td><tt>#182349</tt></td></tr>
.
34c
<tr><td class="eg" style="background: #66ccff;"> </td><td><tt>#xxxxxx</tt></td></tr>
.
20,23d
The numbers are line numbers, line number ranges are separated with commas. Then there are three single letter commands:
a: add the next block of text at this position.
c: change the text at this position to the following block. This is equivalent to a d followed by an a command.
d: delete these lines.
You'll also notice that the line numbers in the patch go from the bottom up so you don't have to worry about changes messing up the lines numbers in subsequent chunks of the patch. The actual chunks of text to be added or changed follow the commands as a sequence of lines terminated by a line with a single period (i.e. /^\.$/ or patch_line == '.' depending on your preference). In summary, the format looks like this:
[line-number-range][command]
[optional-argument-lines...]
[dot-terminator-if-there-are-arguments]
So, to apply an ed patch, all you need to do is load the target file into an array (one element per line), parse the patch using a simple state machine, call Array#insert to add new lines and Array#delete_at to remove them. Shouldn't take more than a couple dozen lines of Ruby to write the patcher and no library is needed.
If you can arrange your XML to come out like this:
<tag>
blah blah
</tag>
<other-tag x="y">
mumble mumble
</other>
rather than:
<tag>blah blah</tag><other-tag x="y">mumble mumble</other>
then the above simple line-oriented approach will work fine; the extra EOLs aren't going to cost much space so go for easy implementation to start.
There are Ruby libraries for producing diffs between two arrays (google "ruby algorithm::diff" to start). Combining a diff library with an XML parser will let you produce patches that are tag-based rather than line-based and this might suit you better. The important thing is the choice of patch formats, once you choose the ed format (and realize the wisdom of the patch working from the bottom to the top) then everything else pretty much falls into place with little effort.
I know this question is almost five years old, but I'm going to post an answer anyway. When searching for how to make and apply patches for strings in Ruby, even now, I was unable to find any resources that answer this question satisfactorily. For that reason, I'll show how I solved this problem in my application.
Making Patches
I'm assuming you're using Linux, or else have access to the program diff through Cygwin. In that case, you can use the excellent Diffy gem to create ed script patches:
patch_text = Diffy::Diff.new(old_text, new_text, :diff => "-e").to_s
Applying Patches
Applying patches is not quite as straightforward. I opted to write my own algorithm, ask for improvements in Code Review, and finally settle on using the code below. This code is identical to 200_success's answer except for one change to improve its correctness.
require 'stringio'
def self.apply_patch(old_text, patch)
text = old_text.split("\n")
patch = StringIO.new(patch)
current_line = 1
while patch_line = patch.gets
# Grab the command
m = %r{\A(?:(\d+))?(?:,(\d+))?([acd]|s/\.//)\Z}.match(patch_line)
raise ArgumentError.new("Invalid ed command: #{patch_line.chomp}") if m.nil?
first_line = (m[1] || current_line).to_i
last_line = (m[2] || first_line).to_i
command = m[3]
case command
when "s/.//"
(first_line..last_line).each { |i| text[i - 1].sub!(/./, '') }
else
if ['d', 'c'].include?(command)
text[first_line - 1 .. last_line - 1] = []
end
if ['a', 'c'].include?(command)
current_line = first_line - (command=='a' ? 0 : 1) # Adds are 0-indexed, but Changes and Deletes are 1-indexed
while (patch_line = patch.gets) && (patch_line.chomp! != '.') && (patch_line != '.')
text.insert(current_line, patch_line)
current_line += 1
end
end
end
end
text.join("\n")
end