How to get x and y coordinate of mouseClick - winforms

I am trying to achieve painting a rectangle around the center of mouseClick position. For that i feel i need to obtain the x and y coordinate as an int.
(This is edited code and e.X or e.Y is the solutions to this question)
let mouseClick (e: MouseEventArgs) =
let x = e.X
let y = e.Y
let coords = [|System.Drawing.Point((x-10),(y-10));
System.Drawing.Point((x-10),(y+10));
System.Drawing.Point((x+10),(y+10));
System.Drawing.Point((x+10),(y-10));
System.Drawing.Point((x-10),(y-10))|]
window.Paint.Add(fun e -> e.Graphics.DrawLines(pen, coords ))
window.MouseClick.Add mouseClick
I tried using the e.Location property that doesn't work which makes sense to some extend since when i print it then it prints "x=(some number) y=(some number)"
Can any one help me obtaining the x and y coordinate as an int?

As stated in the comment, to get mouse position from a MouseEventArgs you simply need to access it's X or Y properties
which just reflects the Location.X and Location.Y properties also available on e
Regarding your edit and your additional comment, I think you've done something wrong by adding a new Paint handler with each click and you just need to draw (which probably still requires a Refresh at some point though)
let mouseClick (e: MouseEventArgs) =
let x = e.X
let y = e.Y
let coords = [| System.Drawing.Point(x - 10, y - 10)
System.Drawing.Point(x - 10, y + 10)
System.Drawing.Point(x + 10, y + 10)
System.Drawing.Point(x + 10, y - 10)
System.Drawing.Point(x - 10, y - 10) |]
// maybe use instead of let ?
let g = window.CreateGraphics()
g.Graphics.DrawLines(pen, coords)
window.MouseClick.Add mouseClick

Related

In F#, how to correctly use ResizeArray() and an accumulator in an Array.map to change the property of a record

(Newbie question). Simple question.
In C#, I have the following code:
double openspace = (WorkArea.Width - totalcolumnwidth) / (ColumnCount - 1);
double left = WorkArea.Left;
for (int k = 0; k < ColumnCount; k++)
{
Cursor cursor = new Cursor
{
TopLeft = new Point(left, WorkArea.Top),
};
cursors.Add(cursor);
left += Columns[k] + openspace;
}
In F#, I've tried this for simplicity but it fails.
type Cursor = { TopLeft: float }
let columnCount = 5.0 // // columnCount number of cursors in List<Cursor>
let cursors = new ResizeArray<Cursor>(columnCount)
let mutable left = 20.0
cursors |> Array.map ( fun k -> left <- left + 10 + k.TopLeft ; {k with TopLeft = left} )
The goal here is to calculate a new TopLeft value for each Cursor in the cursors array based on an accumalator in 'left' and return a new cursors array with each cursor record having its new value.
How is this done correctly? Can it be done without using a mutable "left" variable?
Thank you in advance.
#Addendum: The "columns" is defined as an array of integers (each integer representing the width of a column).
columns = [|210; 330|]
I don't think you need a fold (or, to be more precise, a scan) to handle this, because the current TopLeft value can actually be computed without reference to the previous TopLeft value. This is a good case for an array comprehension. Something like this:
let cursors =
[|
for i = 0 to columnCount-1 do
yield { TopLeft = initialOffset + (columnOffset * float i) }
|]
This works because the columns are constant-width. For variable-width columns, you would definitely need a scan, like this:
let columnWidths = [| 210; 340; 200; 300 |]
let initialOffset = 100 // left coord of first column
let columnOffset = 20 // gap between columns
let columnLefts =
(initialOffset, columnWidths)
||> Seq.scan (fun acc width ->
acc + width + columnOffset)
|> Seq.take columnWidths.Length // ignore final value
|> Seq.toArray
printfn "%A" columnLefts
The output is: 100,330,690,910

How to expand 2d array (30x20) to 36x60, which is contained in 620x480 2d array?

The start data: 2d array (620x480) is contained image, where shows human face, and 2d array (30x20) which is contained eye image. Face image includes eye image.
How I can expand eye image to 36x60 to include pixels from face image? Are there ready-made solutions?
Another similar task: the eye image have 37x27 size. How I can expand eye image to target(closest to 36x60) size, e.g. 39x65 i.e maintain the aspect ratio required before resizing and then resize to 36x60.
Code for testing (project is available by reference):
import dlib
import cv2 as cv
from imutils.face_utils import shape_to_np
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('res/model.dat')
frame = cv.imread('photo.jpg')
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
img = frame.copy()
dets = detector(gray, 0)
for i, det in enumerate(dets):
shape = shape_to_np(predictor(gray, det))
shape_left_eye = shape[36:42]
x, y, h, w = cv.boundingRect(shape_left_eye)
cv.rectangle(img, (x, y), (x + h, y + w), (0, 255, 0), 1)
cv.imwrite('file.png', frame[y: y+w, x: x+h])
The image 42x13:
For the first part you can use cv2.matchTemplate to find the eye region in the face and then according to the size you want you can enlarge it. You can read more about it here.
FACE IMAGE USED
EYE IMAGE USED
The size of eye I have (12, 32).
face = cv2.imread('face.jpg', 0)
eye = cv2.imread('eye.jpg', 0)
w, h = eye.shape[::-1]
res = cv2.matchTemplate(face,eye,cv2.TM_CCOEFF)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(face ,top_left, bottom_right, 255, 2)
cv2.imshow('image', face)
cv2.waitKey(0)
cv2.destroyAllWindows()
The result with this code is:
Now I have the top left and bottom right co-ordinates of the eye that is matched where top_left = (112, 108) and bottom_right = (144, 120). Now to expand them to dimensions of 36x60 I simply subtract the required values from top_left and add the required values in bottom_right.
EDIT 1
The question has been edited which suggests that dlib has been used along with a model trained to perform left eye detection. Using the same code I obtained
After that as proposed above I find top_left = (x,y) and bottom_right = (x+w, y+h).
Now if the eye size is smaller 36x60 then we just have to take the area around it to expand it to 36x60 otherwise we have to expand it as such that the aspect ratio is not disturbed and then resized and it cannot be hard coded. The full code used is:
import dlib
from imutils.face_utils import shape_to_np
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('res/model.dat')
face = cv2.imread('face.jpg', 0)
img = face.copy()
dets = detector(img, 0)
for i, det in enumerate(dets):
shape = shape_to_np(predictor(img, det))
shape_left_eye = shape[36:42]
x, y, w, h = cv2.boundingRect(shape_left_eye)
cv2.rectangle(face, (x, y), (x + w, y + h), (255, 255, 255), 1)
top_left = (x, y)
bottom_right = (x + w, y + h)
if w <= 36 and h <= 60:
x = int((36 - w)/2)
y = int((60 - h)/2)
else:
x1 = w - 36
y1 = h - 60
if x1 > y1:
x = int((w % 3)/2)
req = (w+x) * 5 / 3
y = int((req - h)/2)
else:
y = int((h % 5)/2)
req = (y+h) * 3 / 5
x = int((req - w)/2)
top_left = (top_left[0] - x, top_left[1] - y)
bottom_right = (bottom_right[0] + x, bottom_right[1] + y)
extracted = face[top_left[1]:bottom_right[1], top_left[0]:bottom_right[0]]
result = cv2.resize(extracted, (36, 60), interpolation = cv2.INTER_LINEAR)
cv2.imshow('image', face)
cv2.imshow('imag', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Which gives us a 36x60 region of the eye:
This takes care of the case when size of eye is smaller than 36x60. For the second case when the size of eye is larger than 36x60 region I used face = cv2.resize(face, None, fx=4, fy=4, interpolation = cv2.INTER_CUBIC). The result was:
The size of eye detected is (95, 33) and the extracted region is (97, 159) which is very close to the aspect ration of 3:5 before resizing which also satisfies that second task.

Polyline() - change colour with an array value

I'm trying to create a very simple example of a for steps in [] loop using a Polyline() inside an IronPython WPF application. Each iteration of the loop should draw a different colour however Brushes implements a set of predefined System.Windows.Media.SolidColorBrush objects. I can't work out how to swap Red for my steps variable.
def polylineShape(self):
x = self.myCanvas.Width/2
y = self.myCanvas.Height/2
polyline = Polyline()
polyline.StrokeThickness = 5
for steps in ['Red','Blue','Green','Black']:
x = x
y = x
polyline.Points.Add(Point(x,y))
x = x + 40
polyline.Points.Add(Point(x,y))
polyline.Stroke = Brushes.Red #change colour on iteration
self.myCanvas.Children.Add(polyline)
I created a solution with some trial and error, I couldn't work out how to pass colours directly to the Brushes type.
def polylineShape(self):
x = 0
y = 0
for steps in [Brushes.SteelBlue, Brushes.DarkOrange, Brushes.DarkSeaGreen, Brushes.Honeydew]:
polyline = Polyline()
polyline.StrokeThickness = self.myCanvas.Height/4
x = 0
y = y + self.myCanvas.Height/4
polyline.Points.Add(Point(x,y))
x = self.myCanvas.Width
polyline.Points.Add(Point(x,y))
polyline.Stroke = steps
self.myCanvas.Children.Add(polyline)

Direction, Orientation object

How do I move an object according to its orientation? I mean, I have a cube in one position, I want to rotate about the Y axis and move according to their orientation. Then move and rotate again to change your direction. Something like this:
in JS you can try something like this:
var previousPosition = [x, y]; //change x and y with the coordinate of the object
var nextPosition = [x, y]; //change x and y with the new coordinate of the object
var x = previousPosition[0] - previousPosition[0];
var y = nextPosition[1] - nextPosition[1];
var rad = Math.atan(y/x);
var deg = rad * 180 / 3.14;
in the variable deg you have the value in degree to rotate your cube

Trouble datamining with Django

I've set up a Django project in which i create random points. These random points are stored in a database(sqlite) (i can see them via the admin website and change the values, so this works).
If i the write a script i can access the points and print them in a plot. See code below.
But if I then want to mine these points to sort them or only plot a selection of the dataset i seem to have trouble. If i readout the values they are not connected anymore and sorting x would mix up the point set.
Is there a way to sort the data set to a minimum value of in this case X and the sort the values and print the set? (keep all x, y, z and name value of the point intact?) (see answer below, point in Point3D.objects.all().order_by('x'):)
If i now want to to have the values of x between x = 12 and x = 30? how can i add this extra filter?
My code is as follows:
models.py:
class Point3D(models.Model):
name = models.CharField(max_length = 10)
x = models.DecimalField(max_digits=5, decimal_places=2)
y = models.DecimalField(max_digits=5, decimal_places=2)
z = models.DecimalField(max_digits=5, decimal_places=2)
generate the points:
from books.models import Point3D
def points():
for i in range(20):
x = random.randint(0,100)
y = random.randint(0,100)
z = random.randint(0,100)
p = Point3D(name = x , x = x ,y = y,z = z)
# print 'test'
p.save()
#
points()
in views.py:
def ThreeGraphs(request):
fig = Figure()
fig.suptitle('2D-punten')
ax = fig.add_subplot(111)
for point in Point3D.objects.all():
print point
name = int(point.name)
xs = int(point.x)
ys = int(point.y)
zs = int(point.z)
print (xs, ys, zs)
ax.plot(xs, ys, 'bo' )
HttpResponse(mimetype="image/png")
FigureCanvas(fig)
fig.savefig('template/images/testing.png')
picture = "testing.png"
return render_to_response('Test.html', {'picture': picture}, RequestContext(request))
Hope anyone knows how to solve my trouble.
Thanks a lot!
Tijl
You need to to this:
for point in Point3D.objects.all().order_by('x'):
This will return the points in sorted order by the 'x' field. You can say order_by('-x') to reverse the sort order.

Resources