Using imagez I can get a pixel from an image as [r g b]. Using this colour wheel I have verified that this extraction part is almost certainly working. This is the imagez code that does the extraction:
(defn components-rgb
"Return the RGB components of a colour value, in a 3-element vector of long values"
([^long rgb]
[(bit-shift-right (bit-and rgb 0x00FF0000) 16)
(bit-shift-right (bit-and rgb 0x0000FF00) 8)
(bit-and rgb 0x000000FF)]))
I need to do the opposite of this extraction. Here are some examples of the 'colour value' (or pixel) being extracted:
First pixel: -6700606 (in HEX: FFFFFFFFFF99C1C2)
Last pixel: -11449516 (in HEX: FFFFFFFFFF514B54)
First as colour: [153 193 194] (in HEX: 99 C1 C2)
Last as colour: [81 75 84] (in HEX: 51 4B 54)
Doing the opposite would mean that [153 193 194] becomes -6700606. This question has been asked before on SO, for example here. Here are two of my attempts which do not work:
;rgb = 0xFFFF * r + 0xFF * g + b
(defn my-rgb-1 [[r g b]]
(+ (* 0xFFFF r) (* 0xFF g) b))
;int rgb = ((r&0x0ff)<<16)|((g&0x0ff)<<8)|(b&0x0ff);
(defn my-rgb-2 [[r g b]]
(let [red (bit-shift-left 16 (bit-and r 0x0FF))
green (bit-shift-left 8 (bit-and g 0x0FF))
blue (bit-and b 0x0FF)]
(bit-or red green blue)))
image --1--> extracted-pixel --2--> rgb colour --3--> to-write-pixel --4--> image
Steps 1 and 2 are working, but step 3 is not. If step 3 were working extracted-pixel would be the same as to-write-pixel.
There is an rgb function in imagez, but it too does not work for me. (The author updated me to say it is not supposed to. See here). I might also add that the imagez function get-pixel is first used to get the pixel (step 1), followed by components-rgb (step 2) as shown above.
Take a look here where I have outlined the steps.
If I understand your poblem correctly - the issue you have is that:
"First pixel" in hex is i.e 0xFFFFFFFFF99C1C2
you convert it to decimal-rgb via `components-rgb` = [153 193 194]
you re-convert [153 193 194] to int via `rbg` and get
0x99C1C2
which by all means is correct
since clojure by default uses long the only thing you need to do
is use a unchecked-int to trucate the long to int as so:
(unchecked-int 0xFFFFFFFFFF99C1C2)
-6700606
which is what you want - right ?
I had the arguments to bit-shift-left in the wrong order. So this is a basic version of the improved my-rgb-2:
(defn my-rgb-2 [[r g b]]
(let [red (bit-shift-left r 16)
green (bit-shift-left g 8)
blue b]
(bit-or red green blue)))
I have left off (bit-and a 0x0FF), (where a is r, g or b), simply because it is only necessary if the number is more than 255, which would not be a proper value anyway. For this answer it doesn't really matter whether it is there or not.
The next thing to do is put all the 0xF (all 4 bits filled in) at the beginning. This nearly gets me there:
(defn my-rgb-2 [[r g b]]
(let [red (bit-shift-left (bit-and r 0x0FF) 16)
green (bit-shift-left (bit-and g 0x0FF) 8)
blue (bit-and b 0x0FF)]
(bit-or 0xFFFFFFFFF000000 (bit-or red green blue))))
Unfortunately if I put one more 0xF on the last line I get:
Exception in thread "main" java.lang.IllegalArgumentException: bit operation not supported for: class clojure.lang.BigInt
But that can be fixed by borrowing from the answer #birdspider gave:
(defn my-rgb-2 [[r g b]]
(let [red (bit-shift-left (bit-and r 0x0FF) 16)
green (bit-shift-left (bit-and g 0x0FF) 8)
blue (bit-and b 0x0FF)]
(bit-or (bit-or red green blue) (unchecked-int 0xFFFFFFFFFF000000))))
The imagez library now has this function, but done as a macro for performance reasons.
Related
I am trying to check if a point is in a cross shape. That looks like this
Not sure how to modify the pnpoly to suit this type of shape
bool PointInPolygon(vector<pair<int,int>> points,int x, int y) {
int i, j, nvert = points.size();
bool c = false;
for(i = 0, j = nvert- 1; i < nvert; j = i++) {
if( ( (points[i].second >= y) != (points[j].second >= y) ) &&
(x <= (points[j].first - points[i].first) * (y - points[i].second) / (points[j].second - points[i].second) + points[i].first)
)
c = !c;
}
Appreciate any help
While googling reveals, that the term "scanline" has gotten a new meaning recently, it used to be the name for an algorithm to detect intersections of lines and other geometric shapes.
The algorithms basic idea is to move a vertical "scan line" across the vertices from left to right and to record the vertical boundaries of the shape at that very x-coordinate (where the scanline is currently positioned).
Given you only have horizontal and vertical lines, the implementation of that idea can simply jump from x-coordinate of a vertex to the next, if the vertices are sorted in ascending order on the x-coordinate.
Since multiple points can share the same x-coordinate, all we need to note is, at that very x-coordinate, which are the highest and lowest y coordinates of those vertices, respectively.
Given that 32degree Celsius summertime heat, I was too lazy to create a C++ version of it. Instead, some quick hacking in Common Lisp. But it should be easy enough to read and translate. Instead of defining some kind of point structure, I simply took complex numbers, where your C++ program uses a std::pair<int,int>. realpart/imagpart obtain the real or imaginary part of a complex number, which, here is simply the x and y component of the vertex.
(defparameter *shape* '(#C(3 3) #C(3 6)
#C(5 6) #C(5 9)
#C(6 9) #C(6 6)
#C(6 3) #C(6 0)
#C(8 0) #C(8 3)
#C(11 3) #C(11 6)))
(defun point-in-shape-p (shape point)
(let ((x-sorted (sort
shape
#'(lambda (p1 p2)
(< (realpart p1)
(realpart p2))))))
(if (< (realpart point)
(realpart (first x-sorted)))
nil
(loop
with x-pivot = -1000000 ;; outside
with y-high = -1000000 ;; outside
with y-low = 100000 ;; outside
for v in x-sorted
when (> (realpart v) x-pivot)
do (progn
(setf x-pivot (realpart v))
(setf y-high -1000000)
(setf y-low 1000000))
when (> (imagpart v) y-high)
do (setf y-high (imagpart v))
when (< (imagpart v) y-low)
do (setf y-low (imagpart v))
when (and (<= (realpart point) x-pivot)
(<= (imagpart point) y-high)
(>= (imagpart point) y-low))
return t))))
Here a few test runs, I did for various points and the shape from your image:
CL-USER> (point-in-shape-p *shape* #C(7 8))
NIL
CL-USER> (point-in-shape-p *shape* #C(7 4))
T
CL-USER> (point-in-shape-p *shape* #C(9 2))
NIL
CL-USER> (point-in-shape-p *shape* #C(9 3))
T
No warranties, but I think it is looking good.
I want to draw an sketch with eight pattern. Now I know how to draw circles in counterclockwise and clockwise directions. But I do not know how to combine them.
(defn draw-state [state]
(let [x (* 150 (quil.core/cos angle))
y (* 150 (quil.core/sin angle))]
(quil.core/ellipse x y 100 100)
(quil.core/ellipse y x 100 100)))
This function will draw two circles in opposite directions. But how to draw a sketch with 8 pattern?
A polar equation for an 8-type of curve =
r^2 = Cos[2t] (Sec[t])^4
where r = radius, t = angle
You could start with this.
I am using the following function to try to create a 64-bit hash of a string, but it is failing with an ArithmeticException even though I am using the "unchecked" version of the arithmetic operators.
user> (reduce (fn [h c]
(unchecked-add (unchecked-multiply h 31) (long c)))
1125899906842597
"hello")
ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1388)
What am I doing wrong here?
have a hint here:
for whatever reason the first param in a function here is treated as integer. Adding type hint helps to solve this problem:
user> (reduce (fn [^long h c]
(unchecked-add (unchecked-multiply h 31) (long c)))
1125899906842597
"hello")
7096547112155234317
update:
moreover: it looks that it comes from the unchecked-multiply
user> (reduce (fn [h c]
(unchecked-add (unchecked-multiply ^long h 31) (long c)))
1125899906842597
"hello")
7096547112155234317
i will make some additional research, and update here, in case of any new information
update 2:
ok, that's what i've found out:
looking at the clojure's documentation at https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Numbers.java
we can see the following:
our case
static public Number unchecked_multiply(Object x, long y){return multiply(x,y);}
leads to:
static public Number multiply(Object x, long y){
return multiply(x,(Object)y);
}
then:
static public Number multiply(Object x, Object y){
return ops(x).combine(ops(y)).multiply((Number)x, (Number)y);
}
so at the end it calls multiply method from LongOps inner class.
final public Number multiply(Number x, Number y){
return num(Numbers.multiply(x.longValue(), y.longValue()));
}
so finally it leads us to a simple (checked?) multiply:
static public long multiply(long x, long y){
if (x == Long.MIN_VALUE && y < 0)
return throwIntOverflow();
long ret = x * y;
if (y != 0 && ret/y != x)
return throwIntOverflow();
return ret;
}
kaboom!
so i don't know whether it is a bug or the desired behavior, but it looks really weird to me.
so the only thing i could advice, is to always remember to typehint your values when using unchecked math in clojure.
You can get the behaviour you want by avoiding the function calls:
(loop [h 1125899906842597
cs "hello"]
(let [c (first cs)]
(if c
(recur (unchecked-add (unchecked-multiply h 31) (long c))
(rest cs))
h)))
;7096547112155234317
Why this is so, I don't know.
I'm trying to implement a simple logistic regression example in Clojure using the Incanter data analysis library. I've successfully coded the Sigmoid and Cost functions, but Incanter's BFGS minimization function seems to be causing me quite some trouble.
(ns ml-clj.logistic
(:require [incanter.core :refer :all]
[incanter.optimize :refer :all]))
(defn sigmoid
"compute the inverse logit function, large positive numbers should be
close to 1, large negative numbers near 0,
z can be a scalar, vector or matrix.
sanity check: (sigmoid 0) should always evaluate to 0.5"
[z]
(div 1 (plus 1 (exp (minus z)))))
(defn cost-func
"computes the cost function (J) that will be minimized
inputs:params theta X matrix and Y vector"
[X y]
(let
[m (nrow X)
init-vals (matrix (take (ncol X) (repeat 0)))
z (mmult X init-vals)
h (sigmoid z)
f-half (mult (matrix (map - y)) (log (sigmoid (mmult X init-vals))))
s-half (mult (minus 1 y) (log (minus 1 (sigmoid (mmult X init-vals)))))
sub-tmp (minus f-half s-half)
J (mmult (/ 1 m) (reduce + sub-tmp))]
J))
When I try (minimize (cost-func X y) (matrix [0 0])) giving minimize a function and starting params the REPL throws an error.
ArityException Wrong number of args (2) passed to: optimize$minimize clojure.lang.AFn.throwArity (AFn.java:437)
I'm very confused as to what exactly the minimize function is expecting.
For reference, I rewrote it all in python, and all of the code runs as expected, using the same minimization algorithm.
import numpy as np
import scipy as sp
data = np.loadtxt('testSet.txt', delimiter='\t')
X = data[:,0:2]
y = data[:, 2]
def sigmoid(X):
return 1.0 / (1.0 + np.e**(-1.0 * X))
def compute_cost(theta, X, y):
m = y.shape[0]
h = sigmoid(X.dot(theta.T))
J = y.T.dot(np.log(h)) + (1.0 - y.T).dot(np.log(1.0 - h))
cost = (-1.0 / m) * J.sum()
return cost
def fit_logistic(X,y):
initial_thetas = np.zeros((len(X[0]), 1))
myargs = (X, y)
theta = sp.optimize.fmin_bfgs(compute_cost, x0=initial_thetas,
args=myargs)
return theta
outputting
Current function value: 0.594902
Iterations: 6
Function evaluations: 36
Gradient evaluations: 9
array([ 0.08108673, -0.12334958])
I don't understand why the Python code can run successfully, but my Clojure implementation fails. Any suggestions?
Update
rereading the docstring for minimize i've been trying to calculate the derivative of cost-func which throws a new error.
(def grad (gradient cost-func (matrix [0 0])))
(minimize cost-func (matrix [0 0]) (grad (matrix [0 0]) X))
ExceptionInfo throw+: {:exception "Matrices of different sizes cannot be differenced.", :asize [2 1], :bsize [1 2]} clatrix.core/- (core.clj:950)
using trans to convert the 1xn col matrix to a nx1 row matrix just yields the same error with opposite errors.
:asize [1 2], :bsize [2 1]}
I'm pretty lost here.
I can't say anything about your implementation, but incanter.optimize/minimize expects (at least) three parameters and you're giving it only two:
Arguments:
f -- Objective function. Takes a collection of values and returns a scalar
of the value of the function.
start -- Collection of initial guesses for the minimum
f-prime -- partial derivative of the objective function. Takes
a collection of values and returns a collection of partial
derivatives with respect to each variable. If this is not
provided it will be estimated using gradient-fn.
Unfortunately, I'm not able to tell you directly what to supply (for f-prime?) here but maybe someone else is. Btw, I think the ArityException Wrong number of args (2) passed to [...] is actually quite helpful here.
Edit: Actually, I think the docstring above is not correct, since the source code does not use gradient-fn to estimate f-prime. Maybe, you can use incanter.optimize/gradient to generate your own?
First, Your cost function should have a parameter for theta like your python implementation however your implementation has fixed as initial-value.
Second, if your cost-func is correct, then you can call optimize like this
(optimize (fn [theta] (cost-func theta X y)) [0 0 0])
Hope this can help you.
I have a c/c++ program running on my Linux box that loads up a 24bit bitmap, reads the two headers and then stores the image data into a char* variable. I have verified this works by dumping that variables contents into a raw binary file and compared it to the original bitmap+offset. I used the code from HERE and unmodified and takes care or reordering into RGB and bottom up.
Now if I have a list of coordinates like X, Y, Width, Height how the heck do I translate these into the byte offsets of my image?!
In MY CODE you see that I am calculating the width of one scanline and the glyph location to find Y and then adding a scanline for each y+1. Similarly for X I am iterating over by three bytes at a time. And finally I store those three bytes sequentially into my temporary character array.
In truth I do not need the pixel data as the glyph is a 0xFF or 0x00 with no smoothing. I included it to make sure my bits where accounted for.
HERE is the image I am using.
EDIT: --------------------------------------------
As mentioned below my math was a bit quarky. fixed the line in the i,j,k loop to:
tmpChar[i][j][k] = img.data[(((Y+j) * imgWidth) + (X + i)) * imgBPP + k];
As for my programs output HERE as you can see it loads the bitmap fine and the header info is proper but when I try to display the contents of the tmpChar array its all 0xFF (I used a signed int so 0xFF = -1 and 0x00 = +0)
The layout in memory of the image is (ignoring that I might have reversed R, G and B):
[R of pixel 0] [G of pixel 0] [B of pixel 0] ....... [B of (0, imgWidth-1)] [R of pixel (1, 0)] .....
So to calculate the offset of any given pixel: offset = ((Y * imgWidth) + X) * imgBPP + colorByte.
Giving for your inner loop, as far as I can tell and assuming your X and Y for the character are correct:
tmpChar[i][j][k] = img.data[(((Y+j) * imgWidth) + (x + i)) * imgBPP + k];
I guess that the pixels are stored in a upside-down order in memory, as is usual with BMP file format:
Normally pixels are stored "upside-down" with respect to normal image
raster scan order, starting in the lower left corner, going from left
to right, and then row by row from the bottom to the top of the image
So your code may be reading the wrong block of pixels.