How to loop properly pixel scanning using bitmaps - c#

So here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace GandomTest
{
class Program
{
public static bool SearchPixel(string hexcode)
{
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bitmap as Image);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
Color desiredPixelColor = ColorTranslator.FromHtml(hexcode);
for (int x = 0; x < SystemInformation.VirtualScreen.Width; x++)
{
for (int y = 0; y < SystemInformation.VirtualScreen.Height; y++)
{
Color currentPixelColor = bitmap.GetPixel(x, y);
if (desiredPixelColor == currentPixelColor)
{
Console.WriteLine("Color found!");
Thread.Sleep(10000);
return true;
}
else
{
Console.WriteLine("Not found");
continue;
}
}
}
return false;
}
static void Main(string[] args)
{
SearchPixel("#000000");
Console.ReadKey();
}
}
}
I was trying to loop the pixel recognition so as soon as the pixel is detected write something in console. The thing I do not know how can I make this work properly. I know this probably isn't the fastest way to do it but everytime I run it, and the specified color is on screen, the program does not detect it.

Related

How to overwrite exiting image file?

using ImageMagick;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;
namespace Weather
{
public class RadarPixels
{
public RadarPixels(string imageToChange, string folderToSave)
{
ConvertRadarImages(imageToChange, folderToSave);
}
public static Bitmap Create32bpp(System.Drawing.Image image, Size size)
{
Bitmap bmp = new Bitmap(size.Width, size.Height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.Clear(Color.White);
gr.DrawImage(image, new Rectangle(0, 0, bmp.Width, bmp.Height));
}
return bmp;
}
public void ConvertRadarImages(string imageToChange, string folderToSave)
{
var image1 = Create32bpp(System.Drawing.Image.FromFile(imageToChange), new Size(512, 512));
var image2 = new Bitmap(Properties.Resources.radar_without_clouds);
image1.SetResolution(96, 96);
image2.SetResolution(96, 96);
int tolerance = 64;
var img1 = new LockBitmap(image1);
var img2 = new LockBitmap(image2);
img1.LockBits();
img2.LockBits();
for (int x = 0; x < image1.Width; x++)
{
for (int y = 0; y < image1.Height; y++)
{
Color pixelColor = img1.GetPixel(x, y);
// just average R, G, and B values to get gray. Then invert by 255.
int invertedGrayValue = 255 - (int)((pixelColor.R + pixelColor.G + pixelColor.B) / 3);
if (invertedGrayValue > tolerance) { invertedGrayValue = 255; }
// this keeps the original pixel color but sets the alpha value
img1.SetPixel(x, y, Color.FromArgb(invertedGrayValue, pixelColor));
}
}
img1.UnlockBits();
img2.UnlockBits();
using (Graphics g = Graphics.FromImage(image2))
{
g.CompositingMode = CompositingMode.SourceOver;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(image1, new Point(0, 0));
}
string fileToSave = Path.GetFileName(imageToChange);
image2.Save(Path.Combine(folderToSave, fileToSave), ImageFormat.Png);
}
}
}
in form1
radarPixels = new RadarPixels(savedFile, Path.GetDirectoryName(savedFile));
i'm getting exception error on the line :
image2.Save(Path.Combine(folderToSave, fileToSave), ImageFormat.Png);
System.Runtime.InteropServices.ExternalException: 'A generic error
occurred in GDI+.'
folderToSAve contains : "E:\Downloaded Images\Radar\Tuesday 02.07.2023 at 23.09 PM"
fileToSave contains : "2023_02_07_23_05.png"
the current image file on the hard disk is : 2023_02_07_22_55.png
what i want to do is that after manipulating on the image 2023_02_07_22_55.png to save the changes made overwriting the same file name : 2023_02_07_22_55.png
but getting this exception error.
tried :
image2.Save(Path.Combine(folderToSave, fileToSave), ImageFormat.Png);
but getting the exception error.

EMGU CV freezes system randomly, throws out odd errors on console

I have added EMGU CV (3.1.0.2282) to my project from Nuget.
The problem is the entire system freezes (under debug) sometimes on the line:
CvInvoke.Canny(source, cannyEdges, cannyThreshold, cannyThresholdLinking);
sometimes next line, etc ... I have just rebooted system 4 times already ...
What's more. During first initial operations on the console I have log information that ends like that:
"error: front end compiler failed build" however certain opencv methods go smoothly..
My code goes like this:
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OpenCV.NETTest
{
public class SquareRecognition
{
public SquareRecognition() {}
private void PyrDownUp(UMat source)
{
using (UMat pyrDownGray = new UMat())
{
CvInvoke.PyrDown(source, pyrDownGray);
CvInvoke.PyrUp(pyrDownGray, source);
}
}
private UMat CannyEdges(UMat source)
{
double cannyThresholdLinking = 120.0;
double cannyThreshold = 180.0;//5.0
UMat cannyEdges = new UMat();
CvInvoke.Canny(source, cannyEdges, cannyThreshold, cannyThresholdLinking);
cannyEdges.Save(#"c:\ttt.jpg");
return cannyEdges;
}
private List<RotatedRect> GetRectangles(UMat source)
{
//PyrDownUp(source);
UMat cannyEdges = CannyEdges(source);
List<RotatedRect> boxList = new List<RotatedRect>(); //a box is a rotated rectangle
using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
{
CvInvoke.FindContours(cannyEdges, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
int count = contours.Size;
for (int i = 0; i < count; i++)
{
using (VectorOfPoint contour = contours[i])
using (VectorOfPoint approxContour = new VectorOfPoint())
{
CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.05, true);
if (CvInvoke.ContourArea(approxContour, false) > 250) //only consider contours with area greater than 250
{
if (approxContour.Size == 4) //The contour has 4 vertices.
{
#region determine if all the angles in the contour are within [80, 100] degree
bool isRectangle = true;
Point[] pts = approxContour.ToArray();
LineSegment2D[] edges = PointCollection.PolyLine(pts, true);
for (int j = 0; j < edges.Length; j++)
{
double angle = Math.Abs(
edges[(j + 1) % edges.Length].GetExteriorAngleDegree(edges[j]));
if (angle < 80 || angle > 100)
{
isRectangle = false;
break;
}
}
#endregion
if (isRectangle) boxList.Add(CvInvoke.MinAreaRect(approxContour));
}
}
}
}
}
return boxList;
}
public void FindSquares(string FileName)
{
if (!File.Exists(FileName))
throw new Exception(string.Format("No file: {0}", FileName));
using (UMat uimageGray = new UMat())
{
using (Image<Bgr, Byte> img = new Image<Bgr, byte>(FileName))
{
CvInvoke.CvtColor(img, uimageGray, ColorConversion.Bgr2Gray);
}
var RectList = GetRectangles(uimageGray);
}
}
}
}

put pixel in area according the registration in C#

I need to create a figure (square) where for each client registered in the system, I put a pixel in a chosen location of the square by the client. I have this example . I need a hint in C # on how to get started.This is only exemple to start.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RandomPixelImage
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
int width = 640, height = 320;
//bitmap
Bitmap bmp = new Bitmap(width, height);
//random number
Random rand = new Random();
//create random pixels
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
//generate random ARGB value
int a = rand.Next(256);
int r = rand.Next(256);
int g = rand.Next(256);
int b = rand.Next(256);
//set ARGB value
bmp.SetPixel(x, y, Color.FromArgb(a, r, g, b));
}
}
//load bmp in picturebox1
pictureBox1.Image = bmp;
//save (write) random pixel image
bmp.Save("D:\\Image\\RandomImage.png");
}
}
}
Since you have already made a Bitmap, all you need to do is assign that to PictureBox control:
First add a PictureBox control to your form, and then add this code to get your image onto it.
pictureBox.Image = bmp;
As your example shows, you can use Bitmap.SetPixel() to alter single pixels.

C# AForge.Net image processing drawing on image

I'm using this example:
http://www.aforgenet.com/framework/features/blobs_processing.html
I tried using the last example and show the output in a picture box after button click:
using AForge;
using AForge.Imaging;
using AForge.Imaging.Filters;
using AForge.Math.Geometry;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Image_Processing_testings
{
public partial class Form1 : Form
{
Bitmap image = null;
public Form1()
{
InitializeComponent();
Bitmap bitmap = new Bitmap("C:\\Users\\user\\Desktop\\test.png");
Bitmap gsImage = Grayscale.CommonAlgorithms.BT709.Apply(bitmap);
DifferenceEdgeDetector filter = new DifferenceEdgeDetector();
image = filter.Apply(gsImage);
// process image with blob counter
BlobCounter blobCounter = new BlobCounter();
blobCounter.ProcessImage(image);
Blob[] blobs = blobCounter.GetObjectsInformation();
// create convex hull searching algorithm
GrahamConvexHull hullFinder = new GrahamConvexHull();
// lock image to draw on it
BitmapData data = image.LockBits(
new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadWrite, image.PixelFormat);
int i = 0;
// process each blob
foreach (Blob blob in blobs)
{
List<IntPoint> leftPoints, rightPoints, edgePoints = new List<IntPoint>();
// get blob's edge points
blobCounter.GetBlobsLeftAndRightEdges(blob,
out leftPoints, out rightPoints);
edgePoints.AddRange(leftPoints);
edgePoints.AddRange(rightPoints);
// blob's convex hull
List<IntPoint> hull = hullFinder.FindHull(edgePoints);
Drawing.Polygon(data, hull, Color.Red);
i++;
}
image.UnlockBits(data);
MessageBox.Show("Found: " + i + " Objects");
}
private void button1_Click_1(object sender, EventArgs e)
{
pictureBox1.Image = image;
}
}
}
The result is that i'm getting the image after filter, but without any polygon on it.
I counted the number of blob and got 3 for this picture :
The examples in the link you've provided assume that white pixels belong to the object and black pixels belong to the background. Your image that you've provided is the opposite. Therefore, invert the image before applying the algorithm and that should work.

Got an issue converting a short[] into a bitmap which class should I be using?

need help converting this short[] into a grayscale bmp
Current Error : http://grabilla.com/04c0f-dcadafc9-1274-4cbf-a3a9-dc47d5148c25.html#
the tdata array is a short[] or list< int16>its short grayscale height map
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Windows.Media.Imaging;
using System.Drawing.Imaging;
namespace ConvertSHTtobmp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int h, w;
h = 1536;
w = 1536;
List<byte> tdata = new List<byte>();
using (BinaryReader br = new BinaryReader(File.Open("C:\\Users\\Keith\\Desktop\\StartZone_1536_1536_0.sht", FileMode.Open)))
{
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
byte temp = br.ReadByte();
tdata.Add (temp);
temp = br.ReadByte();
tdata.Add(temp);
}
}
CreateBitmapFromBytes(tdata.ToArray(), w, h);
}
}
private static void CreateBitmapFromBytes(byte[] pixelValues, int width, int height)
{
//Create an image that will hold the image data
Bitmap pic = new Bitmap(width, height, PixelFormat.Format16bppGrayScale);
//Get a reference to the images pixel data
Rectangle dimension = new Rectangle(0, 0, pic.Width, pic.Height);
BitmapData picData = pic.LockBits(dimension, ImageLockMode.ReadWrite, pic.PixelFormat);
IntPtr pixelStartAddress = picData.Scan0;
//Copy the pixel data into the bitmap structure
System.Runtime.InteropServices.Marshal.Copy(pixelValues, 0, pixelStartAddress, pixelValues.Length);
pic.UnlockBits(picData);
pic.Save(#"C:\Users\Keith\Desktop\heightmap.bmp", ImageFormat.Bmp);
}
}
}
https://social.msdn.microsoft.com/Forums/vstudio/en-US/10252c05-c4b6-49dc-b2a3-4c1396e2c3ab/writing-a-16bit-grayscale-image?forum=csharpgeneral
finally found the right search terms after a few hours of searching :)
ok so the above link got me thinking about the following stuff.
the end solution was this
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;
namespace WpfApplication1
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
short[] Buf = new short[64 * 64];
BitmapSource bmpSrc = BitmapSource.Create(
64, 64, 96, 96, PixelFormats.Gray16, null, Buf, 128);
TransformedBitmap transformedBmp = new TransformedBitmap(bmpSrc, new RotateTransform(-90));
PngBitmapEncoder enc = new PngBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(transformedBmp));
using (FileStream fs = new FileStream("D:\\Temp\\Test.png", FileMode.Create))
{
enc.Save(fs);
}
}
}
}
sources:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/1a0919e9-95df-4479-95b8-103e1914e08e/problems-saving-a-12bpp-short-array-as-a-grayscale-bmp?forum=csharpgeneral

Categories