I'm using gnuplot to profile my cuda program. I found especially the width plot feature helpful. It seems however that computeprof offers no way to export or customize the plots generated. Fortunately all the data is stored in csv format so I thought I could do it just myself using gnuplot or something similar. So now to my question: I couldn't find an example to pro create a plot of time blocks can you create such a plot using gnuplot and if so how?
Unfortunately horizontal histograms, as what this style of plot is called in gnuplot, are not easy to create. In gnuplot histograms are natively vertical. If you do however feel the need to have a horizontal histogram, check this blog entry.
For a vertical histogram you need to do the following:
With this data file Data.dat:
A B C D E F G H I J
0.41 0.03 0.74 0.97 0.15 0.05 0.11 0.60 0.25 0.76
and this little gnuplot script:
set style data histogram
set style histogram rowstacked
set style fill solid border -1
set key autotitle columnheader
plot for [i=1:10] "Data.dat" using i
you should be able to receive the result you are looking for (however vertically ;) ). If you still feel the need for a horizontal histogram you can follow the tutorial of the blog. It is not 100% what you are looking for, but it does the vertical - horizontal trick.
Related
I'm trying to OCR an image in order to read the text on it. Original image is of 300 dpi.But all the ROI parts that are used as input parameters for Tesseract call are 96 dpi. I want to find out when is the quality drop happens. It will be possible if there is a way to calculate the DPI value of each vectors that are passed to Tesseract. Tesseract requires minimum 300 DPI for OCR.
Any idea?
My requirement is perspective rotating a user submitted image into a pre-rendered background image (which is actually an image per frame on a video).
The easiest was to use ImageMagick and I wrote a very crude simple bash script to achieve what I needed as follows:
#!/bin/bash
# #author: neurosys
# #Description: Perspective transforms and projects an alpha image
# onto a background image.
if [ $# -ne 11 ]
then
echo 'Usage: ./map_image.sh background.jpg image.png output.jpg x1 y1 x2 y2 x3 y3 x4 y4';
exit;
fi
BG=$1
IMAGE=$2
DEST=$3
TEMP='temp.png'
BG_SIZE_W=$(convert $BG -print "%w\n" /dev/null)
BG_SIZE_H=$(convert $BG -print "%h\n" /dev/null)
IMAGE_W=$(convert $IMAGE -print "%w\n" /dev/null)
IMAGE_H=$(convert $IMAGE -print "%h\n" /dev/null)
X1=$4
Y1=$5
X2=$6
Y2=$7
X3=$8
Y3=$9
X4=${10}
Y4=${11}
OFFSET=15
TRANSFORM="$OFFSET,$OFFSET, $X1,$Y1 $(($IMAGE_W+$OFFSET)),$OFFSET $X2,$Y2 $OFFSET, $(($IMAGE_H+$OFFSET)) $X3,$Y3 $(($IMAGE_W+$OFFSET)), $(($IMAGE_H+$OFFSET)) $X4,$Y4"
echo "Transform matrix: $TRANSFORM"
convert $IMAGE -background transparent -extent $BG_SIZE_W\x$BG_SIZE_H-$OFFSET-$OFFSET $TEMP
convert $TEMP -background transparent -distort Perspective "$TRANSFORM" $TEMP
convert $BG $TEMP -composite $DEST
rm -f $TEMP
However, it takes for about 4 seconds to produce the desired image on my computer as follows:
[neuro#neuro-linux ~]$ time ./map_image.sh bg.png Hp-lovecraft.jpg output.jpg 494 108 579 120 494 183 576 196 && nomacs output.jpg
Transform matrix: 15,15, 494,108 195,15 579,120 15, 267 494,183 195, 267 576,196
real 0m3.852s
user 0m3.437s
sys 0m0.037s
[neuro#neuro-linux ~]$
The order of operations as well as the parameters I use in the above ImageMagick script might not be optimal. So, any opinions or alternatives to achieve what I need are greatly welcome.
The images used for the above example are,
Background
User submitted image
Output
I am wondering if there is a way to speed up this so much so that I can generate frames for a one minute long video (25 fps * 60 sec) under a few seconds?
As a matter of fact, in case this approach fails, I may resort to writing an OpenGL program for this specifically, which I believe will be much faster given hardware leveraging.
Somewhat off-topic note: The background image is prerendered in animation software (3ds Max). In case I resort to writing an opengl renderer, I can import mesh and camera from 3ds Max and do so for better perspective and lighting.
Thanks.
Edit:
With the help of guys over at ImageMagick forum, the bottleneck turned out in the first conversion of -extent, which was unneeded.
I ended up combining all the commands into one:
convert image.png -background transparent +distort Perspective "1,1, 494,108 201,1 579,120 1, 201 494,183 201, 201 576,196" -compose DstOver -composite bg.png out.png
It runs in 0.6 seconds but transparency somehow does not work, so the output image ends up being only the distorted image with black background all around.
Edit:
Someone on ImageMagick forums wrote a very fast and clean script that reduced it to 0.13 seconds.
Here is the link, in case anyone needs it:
https://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=29495&p=132182#p132141
Try using MPC format as your $TEMP instead of PNG. Encoding of MPC is much much faster. It's designed for use as a temporary file, for use with ImageMagick.
MPC actually creates two files, *.mpc and *.cache, so you need to
remove both. In your script, set TEMP=temp.mpc and TEMPCACHE=temp.cache,
and then at the end of the script, rm $TEMP TEMPCACHE
See the MPC entry on the ImageMagick Formats page.
If I get the dimensions of an image using your technique, it takes around 0.4 seconds for width and another 0.4 seconds for height. I mean like this:
BG_SIZE_W=$(convert $BG -print "%w\n" /dev/null) # 0.48 sec
BG_SIZE_H=$(convert $BG -print "%h\n" /dev/null) # 0.48 sec
If you get both the width and the height in one go like this, it takes 0.006 seconds altogether on my machine:
read BG_SIZE_W BG_SIZE_H < <(identify -ping -format "%w %h" bg.png)
I am still looking at the rest of your code.
I am still a beginner in coding. I am currently working on a program in C/C++ that is determining pixel position of a defined mark (which is a black circle with white surroundings) in a photo.
I made a mask from the mark and a vector, which contains mask's every pixel value as it's elements (using Magick++ I summed values for Red, Green and Blue). Vector contains aprox. 10 000 values since the mask is 100x100px. I also used threshold functions for simplifying the image.
Than I made a grid, that is doing the same for the picture, where I want to find the coordinates of the mark. It is basically a loop, that is going throught the image and when the program knows pixel values in the grid it immediately compares them with the mask. Main idea is to find lowest difference between the mask and one of the grid positions.
The problem is however that this procedure of evaluating all grids position takes huge amount of time (e.g. the image has 1920x1080px so more than 2 million vectors containing 10 000 values). I decided to cycle the grid not every pixel but for example every 10th column and row, and than for the best corellation from this procedure I selected area where I used every pixel loop. But, this still takes lot of time.
I would like to ask you, if there is some way of improving this method for better (faster) results or this whole idea is not time efficient and I should use different approach.
Thanks for every advice!
Edit: The program will be used for processing multiple images and on all of them the size will be same. This is the picture after threshold, the mark is the big black dot.
Image
The idea that I find interesting is a pyramidal scheme - or progressive refinement: you find the spot at a lower size image then search only a small rectangle in the larger image.
If you reduce your image by 2 in each dimension then you would reduce the time by 4 plus some search effort in the larger image.
This has some problems: the reduction will affect accuracy I expect. You might miss the spot.
You have to cut the sample (template) by the same so you create a half-size template in this case. As you half half half... the template will get blurred into the surrounding objects so it will not be possible to have a valid template; for half size once I guess the dot has a couple of pixels around it.
As you haven't specified a tool or OS, I will choose ImageMagick which is installed on most Linux distros and is available for OSX and Windows. I am just using it at the command-line here but there are C, C++, Python, Perl, PHP, Ruby, Java and .Net bindings available.
I would use a "Connect Components Analysis" or "Blob Analysis" like this:
convert image.png -negate \
-define connected-components:area-threshold=1200 \
-define connected-components:verbose=true \
-connected-components 8 -auto-level result.png
I have inverted your image with -negate because in morphological operations, the foreground is usually white rather than black. I have excluded blobs smaller than 1200 pixels because your circles seem to have a radius of 22 pixels which makes for an area of 1520 pixels (Pi * 22^2).
That gives this output, which means 7 blobs - one per line - with the bounding box and area of each:
Objects (id: bounding-box centroid area mean-color):
0: 1358x1032+0+0 640.8,517.0 1296947 gray(0)
3: 341x350+1017+287 1206.5,468.9 90143 gray(255)
106: 64x424+848+608 892.2,829.3 6854 gray(255)
95: 38x101+44+565 61.5,619.1 2619 gray(255)
49: 17x145+1341+379 1350.3,446.7 2063 gray(0)
64: 43x43+843+443 864.2,464.1 1451 gray(255)
86: 225x11+358+546 484.7,551.9 1379 gray(255)
Note that, as your circle is 42x42 pixels you will be looking for a blob that is square-ish and close to that size - so I am looking at the second to last line. I can draw that in in red on your original image like this:
convert image.png -fill none -stroke red -draw "rectangle 843,443 886,486" result.png
Also, note that as you are looking for a circle, you would expect the area to be pi * r^2 or around 1500 pixels and you can check that in the penultimate column of the output.
That runs in 0.4 seconds on a reasonable spec iMac. Note that you could divide the image into 4 and run each quarter in parallel to speed things up. So, if you do something like this:
#!/bin/bash
# Split image into 4 (maybe should allow 23 pixels overlap)
convert image.png -crop 1x4# tile-%02d.mpc
# Do Blob Analysis on 4 strips in parallel
for f in tile-*mpc; do
convert $f -negate \
-define connected-components:area-threshold=1200 \
-define connected-components:verbose=true \
-connected-components 8 info: &
done
# Wait for all 4 to finish
wait
That runs in around 0.14 seconds.
I write application where I must process digital signal - array of double. I must the signal decimate, filter etc.. I found a project gnuradio where are functions for this problem. But I can't figure how to use them correctly.
I need signal decimate (for example from 250Hz to 200Hz). The function should be similar to resample function in Matlab. I found, the classes for it are:
rational_resampler_base_fff Class source
fir_filter_fff Class source
...
Unfortunately I can't figure how to use them.
gnuradio and shared library I have installed
Thanks for any advice
EDIT to #jcoppens
Thank you very much for you help.
But I must process signal in my code. I find classes in gnuradio which can solve my problem, but I need help how set them.
Functions which I must set are:
low_pass(doub gain, doub sampling_freq, doub cutoff_freq, doub transition_width, window, beta)
where:
use "window method" to design a low-pass FIR filter
gain: overall gain of filter (typically 1.0)
sampling_freq: sampling freq (Hz)
cutoff_freq: center of transition band (Hz)
transition_width: width of transition band (Hz).
The normalized width of the transition band is what sets the number of taps required. Narrow –> more taps
window_type: What kind of window to use. Determines maximum attenuation and passband ripple.
beta: parameter for Kaiser window
I know, I must use window = KAISER and beta = 5, but for the rest I'm not sure.
The func which I use are: low_pass and pfb_arb_resampler_fff::filter
UPDATE:
I solved the resampling using libsamplerate
I need signal decimate (for example from 250Hz to 200Hz)
WARNING: I expressed the original introductory paragraph incorrectly - my apologies.
As 250 Hz is not related directly to 200 Hz, you have to do some tricks to convert 250Hz into 200Hz. Inserting 4 interpolated samples in between the 250Hz samples, lowers the frequency to 50Hz. Then you can raise the frequency to 200Hz again by decimating by a factor 4.
For this you need the "Rational Resampler", where you can define the subsample and decimate factors. Something like this:
This means you would have to do something similar if you use the library. Maybe it's even simpler to do it without the library. Interpolate linearly between the 250 Hz samples (i.e. insert 4 extra samples between each), then decimate by selecting each 4th sample.
Note: There is a Signal Processing forum on stackexchange - maybe this question might fall in that category...
More information: If you only have to resample your input data, and you do not need the actual gnuradio program, then have a look at this document:
https://ccrma.stanford.edu/~jos/resample/resample.pdf
There are several links to other documents, and a link to libresample, libresample4, and others, which may be of use to you. Another, very interesting, page is:
http://www.dspguru.com/dsp/faqs/multirate/resampling
Finally, from the same source as the pdf above, check their snd program. It may solve your problem without writing any software. It can load floating point samples, resample, and save again:
http://ccrma.stanford.edu/planetccrma/software/soundapps.html#SECTION00062100000000000000
EDIT: And yet another solution - maybe the simplest of all: Use Matlab (or the free Octave version):
pkg load signal
t = linspace(0, 10*pi, 50); % Generate a timeline - 5 cycles
s = sin(t); % and the sines -> 250 Hz
tr = resample(s, 5, 4); % Convert to 200 Hz
plot(t, s, 'r') % Plot 250 Hz in red
hold on
plot(t, tr(1:50)) % and resampled in blue
Will give you:
Background:
I want to be able to take a 2d matrix (an image really), and a set of points defining a polygon, and draw that polygon into the matrix.
Before I run off and reinvent the wheel, I thought I'd ask if anyone knew of any existing libraries or code in Octave that does this. So far, my searches through the Octave packages and google have come up empty.
Failing in that, neither is too hard to implement, but I'm unsure how to draw a filled polygon. Is there an easy/efficient way to tell which points are inside a polygon and which are outside? Thanks.
Edit:
My purpose isn't displaying anything. Actually, what I'm specifically looking at doing is some image processing stuff, like plotting a convex hull, finding its area, finding the parts of the convex hull not in the original object, etc.
I don't see that Gnu Plot actually give me back any data I can work with. If I'm wrong, by all means tell me how. Thanks.
For finding points within a polygon, you can try Darren Engwirda's MATLAB function posted on MATLAB Central: http://www.mathworks.com/matlabcentral/fileexchange/10391
I looked briefly through the code and don't see anything that's particularly MATLAB specific, so it may run as-is in Octave.
EDIT: responding to the OP's edit up top to make it easier to find:
There are a variety of ways to make gnuplot render directly to a file (scroll down to "Terminal") which you can then read in for analysis. For example, you can output to portable bitmap format which is strikingly easy to read and write (if not small and elegant). Note that, by definition, PBM will give you an array of blacks and whites.
For example, check out this use of the "set terminal" and "set output" commands to render to a series of Unix pipes that produce a pbm and then a png file.
End EDIT:
Gnu Octave defaults to using gnuplot for plotting and it happens that gnuplot is quite good at producing filled polygons. Here are some helpful demonstrations of exactly that sort of thing. For example, here are some filled polygons:
# set terminal png transparent nocrop enhanced font arial 8 size 420,320
# set output 'fillcrvs.4.png'
set grid nopolar
set grid xtics nomxtics ytics nomytics noztics nomztics \
nox2tics nomx2tics noy2tics nomy2tics nocbtics nomcbtics
set grid front linetype 0 linewidth 1.000, linetype 0 linewidth 1.000
set key outside right top vertical Right noreverse enhanced autotitles nobox
set title "The red bat: abs(x) with filledcurve xy=2,5"
plot abs(x) with filledcurve xy=2,5
Here's another demonstration script that draws the crazy face at the bottom of the filled curves page:
# set terminal png transparent nocrop enhanced font arial 8 size 420,320
# set output 'fillcrvs.6.png'
unset border
set dummy t,y
set grid nopolar
set grid xtics nomxtics ytics nomytics noztics nomztics \
nox2tics nomx2tics noy2tics nomy2tics nocbtics nomcbtics
set grid layerdefault linetype 0 linewidth 1.000, linetype 0 linewidth 1.000
unset key
set label 1 "gnuplot" at 0, 1.2, 0 centre norotate front nopoint offset character 0, 0, 0
set label 2 "gnuplot" at 0.02, -0.6, 0 centre norotate front nopoint offset character 0, 0, 0
set arrow 1 from -0.1, 0.26, 0 to 0.18, -0.17, 0 head front nofilled linetype 5 linewidth 4.000 size first 0.100,40.000,90.000
set parametric
set size ratio 1 1,1
set noxtics
set noytics
set title "Let's smile with parametric filled curves"
set xrange [ -1.00000 : 1.00000 ] noreverse nowriteback
set yrange [ -1.00000 : 1.60000 ] noreverse nowriteback
plot [t=-pi:pi] sin(t),cos(t) with filledcurve xy=0,0 lt 15, sin(t)/8-0.5,cos(t)/8+0.4 with filledcurve lt 3, sin(t)/8+0.5,cos(t)/8+0.4 with filledcurve lt 3, t/5,abs(t/5)-0.8 with filledcurve xy=0.1,-0.5 lt 1, t/3,1.52-abs(t/pi) with filledcurve xy=0,1.8 lt -1