Draw wave file using picturebox - c#

I want to know the error in the following code.I want to draw the values of array that contains wave file samples.in the form i put panel and inside it picturebox.
private void button1_Click(object sender, EventArgs e)
{
string ss = "test.wav";
double[] xxwav = prepare(ss);
int xmin = 300; int ymin = 250; int xmax = 1024; int ymax = 450;
int xpmin = 0; int xpmax = xxwav.Length; int ypmin = 32767; int ypmax = -32768;
double a = (double)((xmax - xmin)) /(double) (xpmax - xpmin);
double b = (double)(xpmin - (a * xmin));
double c = (double)((ymax - ymin) /(double) (ypmax - ypmin));
double d = (double)(ypmin - (c * ymin));
double xp1,yp1,xp2,yp2;
Pen redPen = new Pen(Color.Red, 1);
Bitmap bmp = new Bitmap(40000, 500);
Graphics g = Graphics.FromImage(bmp);
PointF p1;
PointF p2;
for (int i = 1; i < xxwav.Length; i++)
{
xp1 = a * (i-1) + b;
yp1 = c * xxwav[i-1] + d;
xp2=a * i + b;
yp2=c * xxwav[i] + d;
p1 =new PointF ((float)xp1,(float)yp1);
p2 =new PointF ((float)xp2,(float)yp2);
g.DrawLine(redPen, p1, p2);
}
pictureBox1.Image = bmp;
MessageBox.Show("complete");
}
public static Double[] prepare(String wavePath)
{
Double[] data;
byte[] wave;
byte[] sR = new byte[4];
System.IO.FileStream WaveFile = System.IO.File.OpenRead(wavePath);
wave = new byte[WaveFile.Length];
data = new Double[(wave.Length - 44) / 4];//shifting the headers out of the PCM data;
WaveFile.Read(wave, 0, Convert.ToInt32(WaveFile.Length));//read the wave file into the wave variable
/***********Converting and PCM accounting***************/
for (int i = 0; i < data.Length; i++)
{
data[i] = BitConverter.ToInt16(wave, i * 2) / 32768.0;
}
//65536.0.0=2^n, n=bits per sample;
return data;
}

Your code worked for me only after I fiddled with your transformations and scaling parameters.
I have replaced your code with the scaling and transformation methods available in the System.Drawing namespace. This did gave me a view of one of my wav files. You only have to replace the private void button1_Click(object sender, EventArgs e) implementation.
var xxwav = prepare(wavFile);
// determine max and min
var max = (from v in xxwav
select v).Max();
var min = (from v in xxwav
select v).Min();
// what is our Y-axis scale
var mid = (max - min);
Pen redPen = new Pen(Color.Red, 1);
Bitmap bmp = new Bitmap(this.pictureBox1.Size.Width, this.pictureBox1.Size.Height);
Graphics g = Graphics.FromImage(bmp);
// x / y position (y-axis to the middle)
g.TranslateTransform(
0
, this.pictureBox1.Size.Height / 2);
// scaling according to picturebox size
g.ScaleTransform(
(float)this.pictureBox1.Size.Width / (float)xxwav.Length
, (float)this.pictureBox1.Size.Height / ((float)mid));
//first point
var prev = new PointF(0, (float)xxwav[0]);
// iterate over next points
for (int i = 1; i < xxwav.Length; i++)
{
var next = new PointF((float) i , (float) xxwav[i] );
g.DrawLine(redPen, prev, next);
prev = next;
}
pictureBox1.Image = bmp;

Related

How to implement unsharp masking on emgucv c#

I am trying to implement the unsharp masking method on emgucv using c#.
The python code I have now is (ref):
def unsharp_mask(image, kernel_size=(5, 5), sigma=1.0, amount=1.0, threshold=0):
"""Return a sharpened version of the image, using an unsharp mask."""
# For details on unsharp masking, see:
# https://en.wikipedia.org/wiki/Unsharp_masking
# https://homepages.inf.ed.ac.uk/rbf/HIPR2/unsharp.htm
blurred = cv.GaussianBlur(image, kernel_size, sigma)
sharpened = float(amount + 1) * image - float(amount) * blurred
sharpened = np.maximum(sharpened, np.zeros(sharpened.shape))
sharpened = np.minimum(sharpened, 255 * np.ones(sharpened.shape))
sharpened = sharpened.round().astype(np.uint8)
if threshold > 0:
low_contrast_mask = np.absolute(image - blurred) < threshold
np.copyto(sharpened, image, where=low_contrast_mask)
return sharpened
The c# code I have now cannot do the work as the above code does. Does anyone know how to implement it emgu cv using c#?
public static void GetMat(Image<Gray, byte> srcimg, Image<Gray, byte> imgBlurred, ref Mat dst, int nAmount = 200)
{
float amount = nAmount / 100f;
using (Image<Gray, byte> dst_temp = new Image<Gray, byte>(srcimg.Width, srcimg.Height))
{
for (int v = 0; v < srcimg.Height; v++)
{
for (int u = 0; u < srcimg.Width; u++)
{
byte a = srcimg.Data[v, u, 0]; //Get Pixel Color | fast way
byte b = imgBlurred.Data[v, u, 0];
int c = (int)(a * (1 + amount) - (amount * b));
if (c < 0) c = 0;
if (c > 255) c = 255;
dst_temp.Data[v, u, 0] = (byte)c;
}
}
dst = dst_temp.Mat.Clone();
}
}
public static void getSharpenImage(Mat src, ref Mat dst, int nAmount = 200, double sigma = 3, int threshold = 0)
{
float amount = nAmount / 100.0F;
using (Mat imgBlurred = new Mat())
{
CvInvoke.GaussianBlur(src, imgBlurred, new System.Drawing.Size(0, 0), sigma, sigma);
using (Mat mask_temp = new Mat())
{
CvInvoke.AbsDiff(src, imgBlurred, mask_temp);
using (Mat lowcontrastmask = new Mat())
{
CvInvoke.Threshold(mask_temp, lowcontrastmask, threshold, 255, ThresholdType.BinaryInv);
GetMat(src.ToImage<Gray, byte>(), imgBlurred.ToImage<Gray, byte>(), ref dst);
src.CopyTo(dst, lowcontrastmask);
}
}
}
}
https://www.idtools.com.au/unsharp-masking-python-opencv/ has a python solution.
the following works in C#:
Mat blurredImage = new Mat();
Mat lapImage = new Mat();
CvInvoke.MedianBlur(grayImage, blurredImage, 1);
CvInvoke.Laplacian(blurredImage, lapImage, blurredImage.Depth);
blurredImage -= (0.9*lapImage);

Send Arabic text as Bitmap

I want to Send Arabic text as Bitmap to a POS printer since I could not print Arabic words directly to the printer. I used below code to convert a text to Bitmap :
Convert_ValueToImage("كيكه", "Simplified Arabic Fixed", 12)
public static Bitmap Convert_ValueToImage(string ValueText, string Fontname, int Fontsize)
{
//creating bitmap image
Bitmap ValueBitmap = new Bitmap(1, 1);
//FromImage method creates a new Graphics from the specified Image.
Graphics Graphics = Graphics.FromImage(ValueBitmap);
// Create the Font object for the image text drawing.
Font Font = new Font(Fontname, Fontsize);
// Instantiating object of Bitmap image again with the correct size for the text and font.
SizeF stringSize = Graphics.MeasureString(ValueText, Font);
ValueBitmap = new Bitmap(ValueBitmap, (int)stringSize.Width, (int)stringSize.Height);
Graphics = Graphics.FromImage(ValueBitmap);
//Draw Specified text with specified format
Graphics.DrawString(ValueText, Font, Brushes.Black, 0, 0);
Font.Dispose();
Graphics.Flush();
Graphics.Dispose();
return ValueBitmap; //return Bitmap Image
}
and when I assign it to pictureBox it works.
Now I want to send it to the printer. I used below method to convert the bitmap image to string with adding the image mode to the string:
public string GetArabic(Bitmap ArabicText)
{
string logo = "";
BitmapData data = GetArabicBitmapData(ArabicText);
BitArray dots = data.Dots;
byte[] width = BitConverter.GetBytes(data.Width);
int offset = 0;
MemoryStream stream = new MemoryStream();
BinaryWriter bw = new BinaryWriter(stream);
bw.Write((char)0x1B);
bw.Write('#');
bw.Write((char)0x1B);
bw.Write('3');
bw.Write((byte)24);
while (offset < data.Height)
{
bw.Write((char)0x1B);
bw.Write('*'); // bit-image mode
bw.Write((byte)33); // 24-dot double-density
bw.Write(width[0]); // width low byte
bw.Write(width[1]); // width high byte
for (int x = 0; x < data.Width; ++x)
{
for (int k = 0; k < 3; ++k)
{
byte slice = 0;
for (int b = 0; b < 8; ++b)
{
int y = (((offset / 8) + k) * 8) + b;
// Calculate the location of the pixel we want in the bit array.
// It'll be at (y * width) + x.
int i = (y * data.Width) + x;
// If the image is shorter than 24 dots, pad with zero.
bool v = false;
if (i < dots.Length)
{
v = dots[i];
}
slice |= (byte)((v ? 1 : 0) << (7 - b));
}
bw.Write(slice);
}
}
offset += 24;
bw.Write((char)0x0A);
}
// Restore the line spacing to the default of 30 dots.
bw.Write((char)0x1B);
bw.Write('3');
bw.Write((byte)30);
bw.Flush();
byte[] bytes = stream.ToArray();
return logo + Encoding.Default.GetString(bytes);
}
public BitmapData GetArabicBitmapData(Bitmap bmpFileName)
{
using (var bitmap = bmpFileName )
{
var threshold = 127;
var index = 0;
double multiplier = 570; // this depends on your printer model. for Beiyang you should use 1000
double scale = (double)(multiplier / (double)bitmap.Width);
int xheight = (int)(bitmap.Height * scale);
int xwidth = (int)(bitmap.Width * scale);
var dimensions = xwidth * xheight;
var dots = new BitArray(dimensions);
for (var y = 0; y < xheight; y++)
{
for (var x = 0; x < xwidth; x++)
{
var _x = (int)(x / scale);
var _y = (int)(y / scale);
var color = bitmap.GetPixel(_x, _y);
var luminance = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11);
dots[index] = (luminance < threshold);
index++;
}
}
return new BitmapData()
{
Dots = dots,
Height = (int)(bitmap.Height * scale),
Width = (int)(bitmap.Width * scale)
};
}
}
this code print a black Rectangle. what would help me is if I could print the text with white background and the size is small as the text size.

I converted a CSV file to shapefile, but can't create its projection

I tried to convert a csv file to shapefile with its projection. Conversion works but I can't create the .prj file.
The error says that
"there is no source code available for current location".
My code is as follows:
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
AxMap axMap1 = new AxMap();
Shapefile sf = new Shapefile();
bool result = sf.CreateNewWithShapeID("", ShpfileType.SHP_POLYGON);
if (!result) {
MessageBox.Show(sf.get_ErrorMsg(sf.LastErrorCode));
} else {
double xMin = 0.0;
double yMin = 0.0;
double xMax = 1000.0;
double yMax = 1000.0;
Random rnd = new Random(DateTime.Now.Millisecond);
int fldX = sf.EditAddField("x", FieldType.DOUBLE_FIELD, 9, 12);
int fldY = sf.EditAddField("y", FieldType.DOUBLE_FIELD, 9, 12);
int fldArea = sf.EditAddField("area", FieldType.DOUBLE_FIELD, 9, 12);
// In a loop we are creating 100 different points using the box established above.
for (int i = 0; i < 100; i++) {
if (i % 10 == 0) {
Shape shp1 = new Shape();
shp1.Create(ShpfileType.SHP_POLYGON);
sf.EditInsertShape(shp1, ref i);
} else {
double xCenter = xMin + (xMax - xMin) * rnd.NextDouble();
double yCenter = yMin + (yMax - yMin) * rnd.NextDouble();
// random radius from 10 to 100
double radius = 10 + rnd.NextDouble() * 90;
// polygons must be clockwise
Shape shp = new Shape();
shp.Create(ShpfileType.SHP_POLYGON);
for (int j = 0; j < 37; j++) {
Point pnt = new Point();
pnt.x = xCenter + radius * Math.Cos(j * Math.PI / 18);
pnt.y = yCenter - radius * Math.Sin(j * Math.PI / 18);
shp.InsertPoint(pnt, ref j);
}
sf.EditInsertShape(shp, ref i);
sf.EditCellValue(fldX, i, xCenter.ToString());
sf.EditCellValue(fldY, i, yCenter.ToString());
sf.EditCellValue(fldArea, i, Math.PI * radius * radius);
}
}
axMap1.CreateControl();
axMap1.AddLayer(sf, true);
axMap1.ZoomToLayer(0);
sf.Categories.Generate(fldArea, tkClassificationType.ctNaturalBreaks, 7);
ColorScheme scheme = new ColorScheme();
scheme.SetColors2(tkMapColor.Wheat, tkMapColor.Salmon); sf.Categories.ApplyColorScheme(tkColorSchemeType.ctSchemeGraduated, scheme);
axMap1.Redraw();
sf.SaveAs(#"D:\shp1\polygons.shp", null);
sf.Open("D:\\shp1\\polygons.shp");
sf.Projection = (DotSpatial.Projections.KnownCoordinateSystems.Projected.UtmWgs1984.WGS1984UTMZone32N).ToString();
sf.SaveAs(#"D:\shp1\polygons.prj");
}
}

Emgu cv Perspective Transform

I'm working emgucv project, But I have problem.
I want as a result of this image
I accept the four input coordinates and want to Perspective with a new image.
But my code is impossible...
This is my code:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
Image<Bgr, byte> image = new Image<Bgr, byte>(#"C:\Users4.jpg");
Bitmap bitImage;
ImageConverter im = new ImageConverter();
int w, h;
int count = 4;
int a = 0;
HomographyMatrix homography;
PointF[] spoint = new PointF[4];
PointF[] dpoint = new PointF[4];
public Form1()
{
InitializeComponent();
}
private void Form1_Shown(object sender, EventArgs e)
{
bitImage = new Bitmap(#"C:\Users4.jpg");
w = bitImage.Width;
h = bitImage.Height;
this.Size = new System.Drawing.Size(w, h);
ibCanvas.BackgroundImage = bitImage;
}
/*
When taking the mouse coordinates being the X and Y axes to the coordinates stored in the Point array.
*/
private void ibCanvas_MouseDown(object sender, MouseEventArgs e)
{
if (count != 0)
{
spoint[a] = new PointF(e.X, e.Y);
a++;
count -= 1;
}
if (count == 0)
{
count = 4;
a = 0;
PointF[] pts1 = new PointF[4];
PointF[] pts2 = new PointF[4];
label1.Text = spoint[0].ToString();
label2.Text = spoint[1].ToString();
label3.Text = spoint[2].ToString();
label4.Text = spoint[3].ToString();
double w1 = Math.Sqrt(Math.Pow(spoint[3].X - spoint[0].X, 2)
+ Math.Pow(spoint[3].X - spoint[0].X, 2));
double w2 = Math.Sqrt(Math.Pow(spoint[2].X - spoint[1].X, 2)
+ Math.Pow(spoint[2].X - spoint[1].X, 2));
double h1 = Math.Sqrt(Math.Pow(spoint[3].Y - spoint[2].Y, 2)
+ Math.Pow(spoint[3].Y - spoint[2].Y, 2));
double h2 = Math.Sqrt(Math.Pow(spoint[0].Y - spoint[1].Y, 2)
+ Math.Pow(spoint[0].Y - spoint[1].Y, 2));
double maxWidth = (w1 < w2) ? w1 : w2;
double maxHeight = (h1 < h2) ? h1 : h2;
dpoint[0].X = 0;
dpoint[0].Y = 0;
dpoint[1].X = 0;
dpoint[1].Y = ((float)maxHeight-1);
dpoint[2].X = ((float)maxWidth - 1); ;
dpoint[2].Y = ((float)maxHeight - 1); ;
dpoint[3].X = ((float)maxWidth - 1); ;
dpoint[3].Y = 0;
homography = CameraCalibration.GetPerspectiveTransform(spoint, dpoint);
Image<Bgr, byte> newImage = image.WarpPerspective(homography, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC, Emgu.CV.CvEnum.WARP.CV_WARP_DEFAULT, new Bgr(0, 0, 0));
CvInvoke.cvShowImage("new Image", newImage);
}
}
}
}
I want really solve this problem
Please Help me!

Draw lines in WPF like in WinForms

How can I draw Lines in WPF so that the result looks like Winforms result?
I've got this image: PictureBox.BackgroundImage
I reverse it to this:
What I get: PictureBox screenshot
Code:
brush := TextureBrush from reversed bitmap
size := 300
barWidth := 25
barSpacing := 5
Result gets PictureBox.Image
public Bitmap CreateSpectrumLine(Brush brush, int size, int barWidth, int barSpacing)
{
using (var pen = new Pen(brush, (float)barWidth))
{
var b = new Bitmap(size, size);
using (var g = Graphics.FromImage(b))
{
g.Clear(Color.Transparent);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
int h = size;
PointData[] points = CalculatePoints(size);
for (int i = 0; i < points.Length; i++)
{
PointData p = points[i];
int barIndex = p.PointIndex;
float x = (float)((barWidth + barSpacing) * barIndex + barWidth / 2);
var p1 = new PointF(x, h + 1);
var p2 = new PointF(x, h - (float)p.Value + 1);
g.DrawLine(pen, p1, p2);
}
}
return b;
}
}
struct PointData
{
public int PointIndex;
public double Value;
}
How can I achieve the same result using WPF components/commands (resulting in an BitmapSource)?

Categories