Im undistorting an image using intrinsic values of camera martix and distortion coeeficient. It corrects the distortion perfectly. But if I load same image twice, sometimes it gives out a blank gray image. Not sure why this is happening.
void distort()
{
Mat cameraMatrix = new Mat(3, 3, DepthType.Cv64F,1);
Mat distCoeffs = new Mat(8, 1, DepthType.Cv64F, 1);
//Camera matrix values
double fx = 5715.63;
double fy = 5788.09;
double cx = 1339.66;
double cy = 941.89;
//double skew = 0.11273;
//Optical distortion coefficient values
double k1 = -2.006166;
double k2 = 5.478401;
//double k3 = 0.001513;
double p1 = 0.007517;
double p2 = -0.007439;
//Set the camera matrix
cameraMatrix.SetValue(0, 0, fx);
cameraMatrix.SetValue(1, 1, fy);
cameraMatrix.SetValue(1, 0, 1);
cameraMatrix.SetValue(0, 2, cx);
cameraMatrix.SetValue(1, 2, cy);
cameraMatrix.SetValue(2, 2, 1);
//Set the distortion matrix
distCoeffs.SetValue(0, 0, k1);
distCoeffs.SetValue(1, 0, k2);
distCoeffs.SetValue(2, 0, p1);
distCoeffs.SetValue(3, 0, p2);
//Read the input image
image = CvInvoke.Imread(#"33.bmp", ImreadModes.Color);
Correct the input image
Mat outFrame = image.Clone();
CvInvoke.Undistort(image, outFrame, cameraMatrix, distCoeffs);
//save the corrected image
image = outFrame.Clone();
imageBox1.Image = image.Bitmap;
image.Dispose();
outFrame.Dispose();
}
Related
help me rotate text image, i want the text to be smooth all the examples that are written in python.
My code.
var src = Cv2.ImRead("NzGFw.png");
var gray = new Mat();
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
var output = new Mat();
Cv2.BitwiseNot(gray, output);
Mat points = Mat.Zeros(output.Size(), output.Type());
Cv2.FindNonZero(output, points);
var box = Cv2.MinAreaRect(points);
Mat squares = src.Clone();
Mat rot = Cv2.GetRotationMatrix2D(box.Center, box.Angle, 1);
Mat rotated = new Mat();
Cv2.WarpAffine(squares, rotated, rot, squares.Size(), InterpolationFlags.Cubic);
Cv2.ImWrite("inclined_text_squares_rotated.jpg", rotated);[![enter image description here][1]][1]
public static float CalcAngle(Mat image)
{
double angle = 0;
var img = new Mat();
var size = image.Size();
Cv2.CvtColor(image, img, ColorConversionCodes.BGR2GRAY);
Cv2.BitwiseNot(img, img);
var lines = Cv2.HoughLinesP(img, 1, Math.PI / 180, 100, size.Width / 2f, 10);
foreach (var line in lines)
img.Line(line.P1, line.P2, Scalar.White, 1, LineTypes.AntiAlias, 0);
for (var i = 0; i < lines.Length; i++)
angle += Math.Atan2(lines[i].P2.Y - lines[i].P1.Y, lines[i].P2.X - lines[i].P1.X);
angle = angle / lines.Length;
return (float)((angle * 180) / Math.PI);
}
I am using a matrix to translate then rotate in 3d (x, y, z) using the xRotate, yRotate, zRotate, depth == 300 vars.
using (var bmp = new SKBitmap(800, 600))
using (var canvas = new SKCanvas(bmp))
using (var paint = new SKPaint())
{
canvas.Clear(SKColors.White);
paint.IsAntialias = true;
// Find center of canvas
var info = bmp.Info;
float xCenter = info.Width / 2;
float yCenter = info.Height / 2;
// Translate center to origin
SKMatrix matrix = SKMatrix.MakeTranslation(-xCenter, -yCenter);
// Use 3D matrix for 3D rotations and perspective
SKMatrix44 matrix44 = SKMatrix44.CreateIdentity();
matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(1, 0, 0, xRotate));
matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 1, 0, yRotate));
matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 0, 1, zRotate));
SKMatrix44 perspectiveMatrix = SKMatrix44.CreateIdentity();
perspectiveMatrix[3, 2] = -1 / depth;
matrix44.PostConcat(perspectiveMatrix);
// Concatenate with 2D matrix
SKMatrix.PostConcat(ref matrix, matrix44.Matrix);
// Translate back to center
SKMatrix.PostConcat(ref matrix,
SKMatrix.MakeTranslation(xCenter, yCenter));
// Set the matrix and display the bitmap
canvas.SetMatrix(matrix);
canvas.DrawBitmap(currentImage, 50, 25, paint);
pictureBox1.Image = bmp.ToBitmap();
}
If I have some Point in the original currentImage, I want to calculate its new location after drawing the transformed image. How can I do that? Would I reuse the matrix to calculate it?
Found the answer. Let the point be (1, 2) in the currentImage. Then simply:
var newPoint = matrix.MapPoint(1, 2);
newPoint =new SkPoint(50 + newPoint.X, 25 + newPoint.Y); // + offsets of DrawImage
Or to draw on a canvas that already mapped using canvas.SetMatrix
var newPoint = new SKPoint(1, 2);
canvas.DrawCircle(newPoint.X + 50, newPoint.Y + 25, 7, paint); // + offsets of DrawImage
I have UserControl of Size 300*200.
and rectangle of size 300*200.
graphics.DrawRectangle(Pens.Black, 0, 0, 300, 200);
When I rotate rectangle in userControl by 30 degree, I get rotated rectangle but it is outsized.
PointF center = new PointF(150,100);
graphics.FillRectangle(Brushes.Black, center.X, center.Y, 2, 2); // draw center point.
using (Matrix matrix = new Matrix())
{
matrix.RotateAt(30, center);
graphics.Transform = matrix;
graphics.DrawRectangle(Pens.Black, 0, 0, 300, 200);
graphics.ResetTransform();
}
I want to fit rectangle like actual result.Check Image here
Can anyone have solution about this.
Thanks.
It's more of a math question than programming one.
Calculate bouning box of any rectangle rotated by any angle in radians.
var newWidth= Math.Abs(height*Math.Sin(angle)) + Math.Abs(width*Math.Cos(angle))
var newHeight= Math.Abs(width*Math.Sin(angle)) + Math.Abs(height*Math.Cos(angle))
Calculate scale for x and y:
scaleX = width/newWidth;
scaleY = height/newHeight;
Apply it to your rectangle.
EDIT:
Applied to your example:
PointF center = new PointF(150, 100);
graphics.FillRectangle(Brushes.Black, center.X, center.Y, 2, 2); // draw center point.
var height = 200;
var width = 300;
var angle = 30;
var radians = angle * Math.PI / 180;
var boundingWidth = Math.Abs(height * Math.Sin(radians)) + Math.Abs(width * Math.Cos(radians));
var boundingHeight = Math.Abs(width * Math.Sin(radians)) + Math.Abs(height * Math.Cos(radians));
var scaleX = (float)(width / boundingWidth);
var scaleY = (float)(height / boundingHeight);
using (Matrix matrix = new Matrix())
{
matrix.Scale(scaleX, scaleY, MatrixOrder.Append);
matrix.Translate(((float)boundingWidth - width) / 2, ((float)boundingHeight - height) / 2);
matrix.RotateAt(angle, center);
graphics.Transform = matrix;
graphics.DrawRectangle(Pens.Black, 0, 0, width, height);
graphics.ResetTransform();
}
I am trying to create a captcha image. I am generating a random string and rotating the text with a random angle and trying to create a byte array. Below is my code snippet:
Image img = Image.FromFile(#"C:\Images\BackGround.jpg");
RectangleF myRect = new RectangleF(0, 0, width, height);
objGraphics.DrawImage(img, myRect);
Matrix myMatrix = new Matrix();
int i = 0;
StringFormat formatter = new StringFormat();
formatter.Alignment = StringAlignment.Center;
for (i = 0; i <= myString.Length - 1; i++)
{
myMatrix.Reset();
int charLenght = myString.Length;
float x = width / (charLenght + 1) * i;
float y = height / 30F;
myMatrix.RotateAt(oRandom.Next(-40, 40), new PointF(x, y));
objGraphics.Transform = myMatrix;
objGraphics.DrawString(myString.Substring(i, 1), MyFont, MyFontEmSizes, MyFontStyles,
MySolidBrush, x, Math.Max(width, height) / 50, formatter );
objGraphics.ResetTransform();
}
Every thing is working fine, except that, the first character in my final image on the web page is crossing my left border of the rectangle. How can I align my text to the center of the rectangle?
Thanks.
I'm trying to rotate a Bitmap with 1Bpp PixelIndex but I've found that it's bugged. When you try to do some of the rotations, a black line will appear on the left side of the image. Doing some research I found that is a bug but probably won't be fixed.
I've tried another way to rotate the Bitmap (I include the code):
Bitmap returnBitmap = new Bitmap(lBitmap.Width, lBitmap.Height);
Graphics g = Graphics.FromImage(returnBitmap);
g.TranslateTransform((float)lBitmap.Width / 2, (float)lBitmap.Height / 2);
g.RotateTransform(180);
g.TranslateTransform(-(float)lBitmap.Width / 2, -(float)lBitmap.Height / 2);
g.DrawImage(lBitmap, new Point(0, 0));
mIsRotated = true;
But my problem here is that the image loses definition when rotated 180º.
Is there any other way to rotate?
I'm sorry if I wasn't clear enough.
If anyone ends here having the same problem, I found a solution. I couldn't use the Bitmap.RotateFlip because it generated a black line, so I tried with that code above. With 180º my images lost some definition, but using -180º solved the problem.
I faced this issue while extracting monochrome bitmaps from icons and cursors.
Flipping is not rotating. This would be better:
Bitmap returnBitmap = new Bitmap(lBitmap.Width, lBitmap.Height);
Graphics g = Graphics.FromImage(returnBitmap);
g.TranslateTransform((float)lBitmap.Width / 2, (float)lBitmap.Height / 2);
// Mirror instead of rotate
g.ScaleTransform(1,-1);
g.TranslateTransform(-(float)lBitmap.Width / 2, -(float)lBitmap.Height / 2);
g.DrawImage(lBitmap, new Point(0, 0));
mIsRotated = true;
However the resulting bitmap will not be 1bpp
This function flips a monochrome bitmap in-place taking advantage of the fact that rows are 32-bit aligned:
/// <summary>
/// Vertically flips a monochrome bitmap in-place
/// </summary>
/// <param name="bmp">Monochrome bitmap to flip</param>
public static void RotateNoneFlipYMono(Bitmap bmp)
{
if (bmp == null || bmp.PixelFormat != PixelFormat.Format1bppIndexed)
throw new InvalidValueException();
var height = bmp.Height;
var width = bmp.Width;
// width in dwords
var stride = (width + 31) >> 5;
// total image size
var size = stride * height;
// alloc storage for pixels
var bytes = new int[size];
// get image pixels
var rect = new Rectangle(Point.Empty, bmp.Size);
var bd = bmp.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);
Marshal.Copy(bd.Scan0, bytes, 0, size);
// flip by swapping dwords
int halfSize = size >> 1;
for (int y1 = 0, y2 = size - stride; y1 < halfSize; y1 += stride, y2 -= stride)
{
int end = y1 + stride;
for (int x1 = y1, x2 = y2; x1 < end; x1++, x2++)
{
bytes[x1] ^= bytes[x2];
bytes[x2] ^= bytes[x1];
bytes[x1] ^= bytes[x2];
}
}
// copy pixels back
Marshal.Copy(bytes, 0, bd.Scan0, size);
bmp.UnlockBits(bd);
}