Line joining in emgucv - line

I have images of the following kind
I want that small lines which I have encircled using yellow, should be combined to form a single line., i.e. if distance between 2 lines is less than some threshold, they should be joined.
I tried using Dilate command of emgucv, but the unwanted lines also get bold.
Thanx in advance :-)

What your after is the Houghline function I provided a method bellow. By changing these settings you can join lines up and only display those with the strongest characteristics. However, this method may struggle since you have a very very noisy image you may want to look into a better edge detection method first before attempting to find those lines.
For every line:
private Image<Bgr, Byte> apply_Hough(Image<Bgr, Byte> Input_Image)
{
LineSegment2D[] lines = Input_Image.HoughLinesBinary(
1, //Distance resolution in pixel-related units
Math.PI / 45.0, //Angle resolution measured in radians.
50, //threshold
100, //min Line width
1 //gap between lines
)[0]; //Get the lines from the first channel
Image<Bgr, Byte> lineImage = img.Copy();
foreach (LineSegment2D line in lines)
Input_Image.Draw(line, new Bgr(Color.Red), 2);
return Input_Image;
}
Hough lines uses and very advanced voting method in which only the strongest lines will be shown and they should be listed accordingly. So also try using a for loop in replace of the foreach loop to only display the first 6 strongest lines such as this.
For the 6 strongest lines:
private Image<Bgr, Byte> apply_Hough(Image<Bgr, Byte> Input_Image)
{
LineSegment2D[] lines = Input_Image.HoughLinesBinary(
1, //Distance resolution in pixel-related units
Math.PI / 90.0, //Angle resolution measured in radians.
50, //threshold
100, //min Line width
1 //gap between lines
)[0]; //Get the lines from the first channel
Image<Bgr, Byte> lineImage = img.Copy();
for (int i = 0; i <= 6; i++)
{
Input_Image.Draw(lines[i], new Bgr(Color.Red), 2);
}
return Input_Image;
}
Hope this helps,
Cheers,
Chris

Related

How to overlap a buffer in Objective-C

I'm trying to do FFT on the iPhone, and I realised that I had not overlapped my input prior to windowing. I was wondering if anyone could give me some insight on to how to properly overlap my input buffer.
I am wanting to overlap bufferSamples by a factor of 4, and I understand that it is to be done using memove functions, but I can't figure out how to get it to work in regard to overlapping.
enum
{
frameSize = 2048,
overlap = 4,
range = 8192,
step = frameSize/overlap,
};
static COMPLEX_SPLIT A;
// For each sample in buffer...
for (int j = 0; j < audioBufferList.mNumberBuffers; j++)
{
// Declaring samples from audio buffer list
SInt16 *bufferSamples = (SInt16*)audioBufferList.mBuffers[j].mData;
// Overlapping here?
////////////////////////
//// vDSP FUNCTIONS ////
////////////////////////
// Creating Hann window function
for (int i = 0; i < frameSize; i++)
{
double window = 0.5 * (1.0 - cos((2.0 * M_PI * i) / (frameSize - 1)));
// Applying window to each sample
A.realp[i] = window * bufferSamples[i];
A.imagp[i] = 0;
}
// Further DSP...
To get an overlap factor of 4, you need to save the last 75% of the data that, before windowing, was input to the previous FFT. Then use that saved data as the first 75% of the current FFT, with only the last 25% from current or not yet used data. memmove can be used to copy data to and from the temporary save data buffers. Repeat as necessary to use up the data available.

Android - Trying to gradually fill a circle bottom to top

I'm trying to fill a round circle (transparent other than the outline of the circle) in an ImageView.
I have the code working:
public void setPercentage(int p) {
if (this.percentage != p ) {
this.percentage = p;
this.invalidate();
}
}
#Override public void onDraw(Canvas canvas) {
Canvas tempCanvas;
Paint paint;
Bitmap bmCircle = null;
if (this.getWidth() == 0 || this.getHeight() == 0 )
return ; // nothing to do
mergedLayersBitmap = Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.ARGB_8888);
tempCanvas = new Canvas(mergedLayersBitmap);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setFilterBitmap(false);
bmCircle = drawCircle(this.getWidth(), this.getHeight());
tempCanvas.drawBitmap(bmCircle, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
tempCanvas.clipRect(0,0, this.getWidth(), (int) FloatMath.floor(this.getHeight() - this.getHeight() * ( percentage/100)));
tempCanvas.drawColor(0xFF660000, PorterDuff.Mode.CLEAR);
canvas.drawBitmap(mergedLayersBitmap, null, new RectF(0,0, this.getWidth(), this.getHeight()), new Paint());
canvas.drawBitmap(mergedLayersBitmap, 0, 0, new Paint());
}
static Bitmap drawCircle(int w, int h) {
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setColor(drawColor);
c.drawOval(new RectF(0, 0, w, h), p);
return bm;
}
It kind of works. However, I have two issues: I run out of memory quickly and the GC goes crazy. How can I utilize the least amount of memory for this operation?
I know I Shouldn't be instantiating objects in onDraw, however I'm not sure where to draw then. Thank you.
pseudo would look something like this.
for each pixel inside CircleBitmap {
if (pixel.y is < Yboundary && pixelIsInCircle(pixel.x, pixel.y)) {
CircleBitmap .setPixel(x, y, Color.rgb(45, 127, 0));
}
}
that may be slow, but it would work, and the smaller the circle the faster it would go.
just know the basics, bitmap width and height, for example 256x256, the circles radius, and to make things easy make the circle centered at 128,128. then as you go pixel by pixel, check the pixels X and Y to see if it falls inside the circle, and below the Y limit line.
then just use:
CircleBitmap .setPixel(x, y, Color.rgb(45, 127, 0));
edit: to speed things up, don't even bother looking at the pixels above the Y limit.
in case if you want to see another solution (perhaps cleaner), look at this link, filling a circle gradually from bottom to top android

Raphael -- How to fit the paper size to the browser's window size?

I want to change the paper(objects base) size of Raphael to fit the window resizing. [ using Firefox_13.0, Raphael_2.1.0, WindowsXP ]
If it is available, I would like to fit full-screen-mode.
==================================================
(steps)
I created the paper : paper = Raphael(0, 50, 800, 600); // initial width and height are 800 and 600.
I placed objects on the paper.
The window size of browser is checked by windowW = window.innerWidth and winnowH = window.innerHeight (on Firefox).
Scaling value is calculated by sv = windowW/800;
And scaling the paper by paper.scale(sv, sv);
==================================================
(the script)
window.onload = function () {
paper = Raphael(0, 50, 800, 600);
var background = paper.rect(0, 0, 800, 600).attr({fill:'#669999'});
// placing the objects
var circle = ...;
var rect = ...;
var ellipse = ...;
winowW = window.innerWidth;
winowH = window.innerHeight;
sv = winowW/800.
paper.scale(sv, sv);
}
==================================================
(result)
Though circle.scale(sv), rect.scale(sv, sv) and ellipse.scale(sv, sv) are valid, paper.scale(sv, sv) and background.scale(sv, sv) are not.
Why this case is happen ? I can get the window size by window.onresize = function() {...} on real-time. If there are better methods, please tell me.
Thanks,
I've succeeded by following two points:
1) "paper" itself is not manipulative object. I think we should look it as billboard.
2) use st = paper.set() and put the objects(circle, rect, ...) in it. And use st.scale(sv, sv, 0, 0);
* third and fourth parameter (0, 0) are very impotent.
(caution)
Serial resizing operation is not good for the function "scale()". Because each of resizing coefficient is piled as the
power of a number. So when one have done 1.1 times resizing operation 5 times, the scale will be 1.1^5.
Use setViewBox()
It should do the work
http://raphaeljs.com/reference.html#Paper.setViewBox

wxGrid shows large empty border on right

By default, wxGrid shows a small ( 10 pixels? ) blank border on the right hand side, after the last column. Calling SetMargins() has no effect on it.
It is irritating, but I can live with it.
However, if I set the the row label width to zero then the blank border grows much larger. If I have just one column, the effect is horrible. It looks like wxGrid is leaving room for the non-existent label.
myPatGrid = new wxGrid(panel,IDC_PatGrid,wxPoint(10,10),wxSize(150,300) );
myPatGrid->SetRowLabelSize(0);
myPatGrid->CreateGrid(200,1);
myPatGrid->SetColLabelValue(0,L"Patient IDs");
Is there a way to remove this border?
Note that if I set the size of the wxgrid window to narrower in the wxGrid constructor, hoping to hide the border, I now get a horizontal scroll bar which is horrible too.
myPatGrid = new wxGrid(panel,IDC_PatGrid,wxPoint(10,10),wxSize(100,300) );
myPatGrid->SetRowLabelSize(0);
myPatGrid->CreateGrid(200,1);
myPatGrid->SetColLabelValue(0,L"Patient IDs");
Gives me
I just upgraded to wxWidgets v2.8.12 - problem still exists.
I didn't find an "autosize" function to fit columns in the grid space.
As a workaround, if you have only one column set its width to
myPatGrid->SetColMinimalWidth(0, grid_width - wxSYS_VSCROLL_X - 10)
otherwise, sum other column's width and adapt the last one to fit the remaining space (minus scrollbar width, minus 10).
EDIT: I have a working example, which produces this:
int gridSize = 150;
int minSize = gridSize - wxSYS_VSCROLL_X - 2; // scrollbar appear if higher
grid->SetRowLabelSize(0);
grid->SetColMinimalWidth(0, minSize);
grid->SetColSize(0, minSize); // needed, otherwise column will not resize
grid->ForceRefresh();
grid->SetColLabelValue(0, "COORD");
EDIT2: I succeded to remove the remaining margin with this:
int gridSize = 150;
int minSize = gridSize - 16; // trial & error
grid->SetMargins(0 - wxSYS_VSCROLL_X, 0);
Solving something similar yesterday I would like to contribute with following what does the job for me. Perhaps this is going to help someone else:
void RecalculateGridSize(wxGrid *grid, int cols) {
if (grid == NULL)
return;
grid->AutoSizeColumns();
float cumulative = 0, param = 0;
for (int i = 0; i < cols; ++i)
cumulative += grid->GetColSize(i);
//not stretching when client size lower then calculated
if(grid->GetClientSize().x < cumulative)
return;
param = (float) grid->GetClientSize().x / cumulative;
for (int i = 0; i < cols; ++i) {
if (i != cols - 1)
grid->SetColSize(i, int(grid->GetColSize(i)*param) - 2); //-2 for each line per column
else
grid->SetColSize(i, int(grid->GetColSize(i)*param)); //leaving last column full to fill properly
}
}
Note: This is doing particularly well when linked with OnSize() event.

Graphics - How may I know if a line is visible onscreen taking account its width

I'm doing some core graphics, and I wonder how I may know if a line will have some parts of it visible on screen.
Let's take a line going from x-5, y3 to x2, y-7. If it's 1 pixel wide, nothing will be displayed onscreen. If it's 15 pixels wide, some parts of it will be displayed.
How may I check that ?
If you have lines only you can work with the function below. Otherwise I would recommend to go through the whole length of your line and create in a specific distance an square of the line width size and check if it is inside your view. An example: If you have a line from x0y0 to x7y0. You would go to x1y0 create a square of your draw line size (in this example 15) and see if this overlaps your screen. Next go to x2y0 and so on. The advantage is it will even work with bezier curves (a little wiki information how bezier work will be enough).
// EDIT: (made a little bezier check function, should work, but haven't tested) And I don't think its more performance efficient to check each line before drawing:
- (void)bezierWithStart:(CGPoint)start cp1:(CGPoint)cp1 cp2:(CGPoint)cp2 end:(CGPoint)end withWidth:(float)wid {
for (float i = 0.0; i<=1.0; i+=0.05) { // how many steps
CGPoint chk1 = CGPointMake(start.x+((cp1.x-start.x)*i), start.y+((cp1.y-start.y)*i));
CGPoint chk2 = CGPointMake(cp1.x+((cp2.x-cp1.x)*i), cp1.y+((cp2.y-cp1.y)*i));
CGPoint chk3 = CGPointMake(cp2.x+((end.x-cp2.x)*i), cp2.y+((end.y-cp2.y)*i));
CGPoint chk4 = CGPointMake(chk1.x+((chk2.x-chk1.x)*i), chk1.y+((chk2.y-chk1.y)*i));
CGPoint chk5 = CGPointMake(chk2.x+((chk3.x-chk2.x)*i), chk2.y+((chk3.y-chk2.y)*i));
CGPoint cPoint = CGPointMake(chk4.x+((chk5.x-chk4.x)*i), chk4.y+((chk5.y-chk4.y)*i));
CGRect drawLine = CGRectMake(cPoint.x-(wid/2), cPoint.y-(wid/2), wid, wid);
// check if rect is in view
}
}
// EDIT end
But now lets go to the simple line function:
- (void)testLine:(CGPoint)fp toSecond:(CGPoint)sp withWidth:(float)wid {
float xratio = sp.x - fp.x;
float yratio = sp.y - fp.y;
double a = sqrt(((wid*wid)*(xratio*xratio))/((yratio*yratio)+(xratio*xratio)));
a/=2; // because line width goes in both direction
double b = (yratio/xratio)*a;
if ((xratio<0.0 && yratio<0.0) || (xratio>0.0 && yratio>0.0))b*=-1;
CGPoint diffFrom1 = CGPointMake(fp.x+a, fp.y+b);
CGPoint diffTo1 = CGPointMake(sp.x+a, sp.y+b);
a*=-1;
b*=-1;
CGPoint diffFrom2 = CGPointMake(fp.x+a, fp.y+b);
CGPoint diffTo2 = CGPointMake(sp.x+a, sp.y+b);
}
you will get 4 points. 2 lines, one above and one below the original line, half the size of your draw width. The calculation behind is to get the draw direction and for that the difference to the original line. But for those who want to get into it, heres my pre calculation: