hi i'm using visual studio 2008 and c++ to implement the watershed algorithm it works well.But i'm recently working on converting the same code into c# using opencvsharp wrapper class in visual studio 2010.I completed most of the code but i couldn't convert uchar ptr into opencvsharp i even use byte data type but it doesn't work.
here is the link to the c++ source code
code.ros.org/trac/opencv/browser/trunk/opencv/samples/c/watershed.cpp?rev=493
and this is where i get the trouble
uchar* ptr = color_tab->data.ptr + i*3;
ptr[0] = (uchar)(cvRandInt(&rng)%180 + 50);
ptr[1] = (uchar)(cvRandInt(&rng)%180 + 50);
ptr[2] = (uchar)(cvRandInt(&rng)%180 + 50);
any help will be appreciated. thank you.
here is the c# code I've been working on, i cant complete the code any help
using (IplImage img0 = new IplImage("1180.jpg", LoadMode.AnyDepth | LoadMode.AnyColor)){
using (IplImage img = img0.Clone())
using (IplImage marker_mask = new IplImage(img0.Size, BitDepth.U8, 1))
using (IplImage markers = new IplImage(img.Size, BitDepth.S32, 1))
using (IplImage img_gray = img0.Clone())
using (IplImage wshed = img0.Clone()){
wshed.Zero();
marker_mask.Zero();
using (CvWindow w_image = new CvWindow("image", WindowMode.AutoSize, img))
{
CvPoint prev_pt = new CvPoint(-1, -1);
w_image.OnMouseCallback += delegate(MouseEvent ev, int x, int y, MouseEvent flags)
{
if (ev == MouseEvent.LButtonUp || (flags & MouseEvent.FlagLButton) == 0)
{
prev_pt = new CvPoint(-1, -1);
}
else if (ev == MouseEvent.LButtonDown)
{
prev_pt = new CvPoint(x, y);
}
else if (ev == MouseEvent.MouseMove && (flags & MouseEvent.FlagLButton) != 0)
{
CvPoint pt = new CvPoint(x, y);
if (prev_pt.X < 0)
{
prev_pt = pt;
}
marker_mask.Line(prev_pt,pt,Cv.ScalarAll(255),5,LineType.Link8,0);
img.Line(prev_pt,pt,Cv.ScalarAll(255),5,LineType.Link8,0);
prev_pt = pt;
w_image.ShowImage(img);
}
};
for (; ; )
{
switch (CvWindow.WaitKey(0))
{
case 27:
return;
case 'r':
marker_mask.Zero();
img0.Copy(img);
w_image.ShowImage(img);
break;
case 'w':
case '\r':
CvSeq<CvPoint> contours;
CvMat color_tab=null;
int i,j,comp_count=0;
CvMemStorage storage = new CvMemStorage();
Cv.FindContours(marker_mask,storage, out contours);
markers.Zero();
for(; contours !=null; contours=contours.HNext,comp_count++){
Cv.DrawContours(markers, contours, Cv.ScalarAll(comp_count+1), Cv.ScalarAll(comp_count+1),-1,-1,LineType.Link8,new CvPoint(0,0));
}
if(comp_count ==0){
continue;
color_tab=Cv.CreateMat(1,comp_count,MatrixType.U8C3);
for(i=0;i<comp_count;i++){
/*
uchar* ptr = color_tab->data.ptr + i*3;
ptr[0] = (uchar)(cvRandInt(&rng)%180 + 50);
ptr[1] = (uchar)(cvRandInt(&rng)%180 + 50);
ptr[2] = (uchar)(cvRandInt(&rng)%180 + 50);
*/
}
{
double t =(double)Cv.GetTickCount();
Cv.Watershed(img0,markers);
Cv.Save(markers,"img0.xml");
t=(double)Cv.GetTickCount()-t;
Console.WriteLine("exec time = %gms\n",t/(Cv.GetTickFrequency()*1000));
}
// paint the watershed image
for(i=0;i<markers.Height;i++)
for(j=0;i<markers.Width;j++)
{
int idx =
}
Cv.AddWeighted(wshed,0.5,img_gray,0.5,0,wshed);
Cv.ShowImage("watershed transform",wshed);
Cv.ReleaseMat(color_tab);
}
}
return 0;
}
}
}
thanks torak but seems it doesn't work i modified the c# code like this
unsafe{
CvRNG rng = new CvRNG();
byte* ptr = (byte*)color_tab.Data.ptr +i*3;
ptr[0] = (byte)(Cv.RandInt(rng)%180 + 50);
ptr[1] = (byte)(Cv.RandInt(rng)%180 + 50);
ptr[2] = (byte)(Cv.RandInt(rng)%180 + 50);
}
It doesn't give any error but i'm not sure about the out put i got a new problem now.I can't convert macro CV_IMAGE_ELEM() in the c++ code into c#.Can anyone help.Thanks for your comments
This is where i get the trouble in c++ code.full c++ code displayed at the beginning of the question
// paint the watershed image
for( i = 0; i < markers->height; i++ )
for( j = 0; j < markers->width; j++ )
{
int idx = CV_IMAGE_ELEM( markers, int, i, j );//markersIPL_DEPTH_32S
uchar* dst = &CV_IMAGE_ELEM( wshed, uchar, i, j*3 );//BGR,j*3
if( idx == -1 ) //-1?
dst[0] = dst[1] = dst[2] = (uchar)255;
else if( idx <= 0 || idx > comp_count ) //
dst[0] = dst[1] = dst[2] = (uchar)0; // should not get here
else //
{
uchar* ptr = color_tab->data.ptr + (idx-1)*3;
dst[0] = ptr[0]; dst[1] = ptr[1]; dst[2] = ptr[2];
}
}
After a quick look, it seems that the way you the data is using the appropriate DataArray... member of color_tab. In your case that would be color_tab.DataArrayByte[...] producing something like:
for (i = 0; i < comp_count * 3; i++)
ptr[i] = (byte)(cvRandInt(...) % 180 + 50);
I haven't looked at the random number generation, and hence I can't test it at the moment, but I suspect it addresses your issue. Fingers crossed.
Related
I have to calculate the spectrum values of an audio.
I used aForge's FFT in Sources/Math/FourierTransform.cs and I used an example of sampling with 16 samples as used in this video to check the results with excel (I tested the results in a spreadsheet like in the video).
FFT:
public enum Direction
{
Forward = 1,
Backward = -1
};
private const int minLength = 2;
private const int maxLength = 16384;
private const int minBits = 1;
private const int maxBits = 14;
private static int[][] reversedBits = new int[maxBits][];
private static Complex[,][] complexRotation = new Complex[maxBits, 2][];
static void Main(string[] args)
{
var Data = new Complex[16];
Data[0] = new Complex(0, 0);
Data[1] = new Complex((float)0.998027, 0);
Data[2] = new Complex((float)0.125333, 0);
Data[3] = new Complex((float)-0.98229, 0);
Data[4] = new Complex((float)-0.24869, 0);
Data[5] = new Complex((float)0.951057, 0);
Data[6] = new Complex((float)0.368125, 0);
Data[7] = new Complex((float)-0.90483, 0);
Data[8] = new Complex((float)-0.48175, 0);
Data[9] = new Complex((float)0.844328, 0);
Data[10] = new Complex((float)0.587785, 0);
Data[11] = new Complex((float)-0.77051, 0);
Data[12] = new Complex((float)-0.68455, 0);
Data[13] = new Complex((float)0.684547, 0);
Data[14] = new Complex((float)0.770513, 0);
Data[15] = new Complex((float)-0.58779, 0);
FFT(Data, Direction.Forward);
for (int a = 0; a <= Data.Length - 1; a++)
{
Console.WriteLine(Data[a].Re.ToString());
}
Console.ReadLine();
}
public static void FFT(Complex[] data, Direction direction)
{
int n = data.Length;
int m = Tools.Log2(n);
// reorder data first
ReorderData(data);
// compute FFT
int tn = 1, tm;
for (int k = 1; k <= m; k++)
{
Complex[] rotation = GetComplexRotation(k, direction);
tm = tn;
tn <<= 1;
for (int i = 0; i < tm; i++)
{
Complex t = rotation[i];
for (int even = i; even < n; even += tn)
{
int odd = even + tm;
Complex ce = data[even];
Complex co = data[odd];
double tr = co.Re * t.Re - co.Im * t.Im;
double ti = co.Re * t.Im + co.Im * t.Re;
data[even].Re += tr;
data[even].Im += ti;
data[odd].Re = ce.Re - tr;
data[odd].Im = ce.Im - ti;
}
}
}
if (direction == Direction.Forward)
{
for (int i = 0; i < n; i++)
{
data[i].Re /= (double)n;
data[i].Im /= (double)n;
}
}
}
private static int[] GetReversedBits(int numberOfBits)
{
if ((numberOfBits < minBits) || (numberOfBits > maxBits))
throw new ArgumentOutOfRangeException();
// check if the array is already calculated
if (reversedBits[numberOfBits - 1] == null)
{
int n = Tools.Pow2(numberOfBits);
int[] rBits = new int[n];
// calculate the array
for (int i = 0; i < n; i++)
{
int oldBits = i;
int newBits = 0;
for (int j = 0; j < numberOfBits; j++)
{
newBits = (newBits << 1) | (oldBits & 1);
oldBits = (oldBits >> 1);
}
rBits[i] = newBits;
}
reversedBits[numberOfBits - 1] = rBits;
}
return reversedBits[numberOfBits - 1];
}
private static Complex[] GetComplexRotation(int numberOfBits, Direction direction)
{
int directionIndex = (direction == Direction.Forward) ? 0 : 1;
// check if the array is already calculated
if (complexRotation[numberOfBits - 1, directionIndex] == null)
{
int n = 1 << (numberOfBits - 1);
double uR = 1.0;
double uI = 0.0;
double angle = System.Math.PI / n * (int)direction;
double wR = System.Math.Cos(angle);
double wI = System.Math.Sin(angle);
double t;
Complex[] rotation = new Complex[n];
for (int i = 0; i < n; i++)
{
rotation[i] = new Complex(uR, uI);
t = uR * wI + uI * wR;
uR = uR * wR - uI * wI;
uI = t;
}
complexRotation[numberOfBits - 1, directionIndex] = rotation;
}
return complexRotation[numberOfBits - 1, directionIndex];
}
// Reorder data for FFT using
private static void ReorderData(Complex[] data)
{
int len = data.Length;
// check data length
if ((len < minLength) || (len > maxLength) || (!Tools.IsPowerOf2(len)))
throw new ArgumentException("Incorrect data length.");
int[] rBits = GetReversedBits(Tools.Log2(len));
for (int i = 0; i < len; i++)
{
int s = rBits[i];
if (s > i)
{
Complex t = data[i];
data[i] = data[s];
data[s] = t;
}
}
}
These are the results after the transformation:
Output FFT results: Excel FFT results:
0,0418315622955561 0,669305
0,0533257974328085 0,716163407
0,137615673627316 0,908647001
0,114642731070279 1,673453043
0,234673940537634 7,474988602
0,0811255020953362 0,880988382
0,138088891589122 0,406276784
0,0623766891658306 0,248854492
0,0272978749126196 0,204227
0,0124250144575261 0,248854492
0,053787064184711 0,406276784
0,00783331226557493 0,880988382
0,0884368745610118 7,474988602
0,0155431246384978 1,673453043
0,0301093757152557 0,908647001
0 0,716163407
The results are not at all similar. Where is it wrong?
Is the implementation of complex (Data) wrong or is the FFT method wrong or other?
Thanks in advance!
First, the resulting FFT is a complex function in general. You're only displaying the real parts in your code but the thing you're comparing to is displaying the magnitudes, so of course they're going to be different: you're comparing apples to oranges.
When you use magnitudes and compare apples to apples, you should get this:
for (int a = 0; a <= Data.Length - 1; a++)
{
Console.WriteLine(Data[a].Magnitude.ToString());
}
...
0.0418315622955561
0.0447602132472683
0.0567904388057513
0.104590813761862
0.46718679147454
0.0550617784710375
0.025392294285886
0.0155534081359397
0.0127641875296831
0.0155534081359397
0.025392294285886
0.0550617784710375
0.46718679147454
0.104590813761862
0.0567904388057513
0.0447602132472683
That looks a little better -- it has the same symmetry property as the Excel output and there appear to be peaks in the same locations.
It almost looks like the scale is off. If I divide each element by the corresponding element from the Excel output, I get:
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
So your results are pretty much correct, just off by a scaling factor.
You're dividing everything by n in the last step of your FFT:
if (direction == Direction.Forward)
{
for (int i = 0; i < n; i++)
{
data[i].Re /= (double)n;
data[i].Im /= (double)n;
}
}
This is conventionally done for the inverse transform, not the forward transform.
In summary, changing the output from Data[a].Re to Data[a].Magnitude and changing the condition at the end of FFT from if (direction == Direction.Forward) to if (direction == Direction.Backward), I get this output:
0.669304996728897
0.716163411956293
0.908647020892022
1.67345302018979
7.47498866359264
0.880988455536601
0.406276708574176
0.248854530175035
0.20422700047493
0.248854530175035
0.406276708574176
0.880988455536601
7.47498866359264
1.67345302018979
0.908647020892022
0.716163411956293
which matches the Excel output.
Right now I try to write a C# Program to translate 8 Base Binary into Text.
But I guess I am not experienced enough with C# to truly make it Work.
I think the code I come up with, should, from a logical Point-of-View somewhat do what I want, but the Syntax isn't properly doing it, since donĀ“t know it better.
This is what I have so far:
using System;
using System.Linq;
using System.Text;
class binaryTranslate
{
public int convertBin(string CodeInput)
{
int [] code = CodeInput.ToArray();
int CodeCount = code.ToString().Length;
int EightBaseSegAmount = CodeCount / 8;
int ByteCapacity = 8;
StringBuilder translated = new StringBuilder();
for (var i = 1; i < EightBaseSegAmount + 1; i++)
{
StringBuilder Byte = new StringBuilder(ByteCapacity);
int ByteStart = (i * 8) - 8;
int ByteEnd = (i * 8) - 1;
int ByteIncrement = 1;
for (var j = ByteStart ; j < ByteEnd + 1; j++)
{
Byte.Append(code[j]);
}
for (var k = 0; k > 7; k++)
{
int BitValue = 128;
if (Byte[k] == 1)
{
if (k > 0)
{
int Squared = Math.Pow(2, k);
ByteIncrement += BitValue / Squared;
}
else
{
ByteIncrement += BitValue;
}
}
}
char toSymbol = Convert.ToChar(ByteIncrement);
translated.Append(toSymbol);
}
return translated;
}
public static int Main()
{
convertBin("010010000110000101101100011011000110111100100001");
}
}
First of all, your code won't compile. Here are the errors/mistakes.
The first one is, at the first line of your function, you are converting the input string to an array using String.ToArray(), which returns a char[] but your try to assign it to a variable (code) typed int[]. You can solve this by replacing the int[] with either char[] or var.
The second one is, inside the second for loop (k = 0; k > 7), you use Math.Pow() and assign it's return value to an int variable (Squared). But Math.Pow returns double. You can solve this by casting the return value of Math.Pow to int. Like; int Squared = (int)Math.Pow(2, k);
The last thing is not easily solvable like the first two because, your code is not exactly correct. You are trying to return something called translated, which is a variable of type StringBuilder. But your function is defined to return an int.
Now these were compile errors. There are a bunch of logical and decision errors/mistakes. Your algorithm also isn't very correct.
Here is a sample code you can use/examine. I'd like to help you further, why your code was incorrect, what was your design mistakes etc. if you want to.
class binaryTranslate
{
public enum IncompleteSegmentBehavior
{
Skip = 0,
ZerosToStart = 1,
ZerosToEnd = 2
}
private byte ConvertBinstrToByte(string sequence)
{
if (string.IsNullOrEmpty(sequence))
return 0; // Throw?
if (sequence.Length != sizeof(byte) * 8)
return 0; // Throw?
const char zero = '0';
const char one = '1';
byte value = 0;
for (int i = 0; i < sequence.Length; i++)
{
if (sequence[i] != zero && sequence[i] != one)
return 0; // Throw
value |= (byte)((sequence[i] - zero) << (7 - i));
}
return value;
}
private string HandleIncompleteSegment(string segment, int segmentSize, IncompleteSegmentBehavior behavior)
{
string result = null;
var zeroAppender = new StringBuilder();
for (int i = 0; i < segmentSize - segment.Length; i++)
zeroAppender.Append('0');
var zeros = zeroAppender.ToString();
switch (behavior)
{
case IncompleteSegmentBehavior.Skip:
break;
case IncompleteSegmentBehavior.ZerosToStart:
result = zeros + result;
break;
case IncompleteSegmentBehavior.ZerosToEnd:
result = result + zeros;
break;
default:
break;
}
return result;
}
public byte[] ConvertBinstrToBytes(string binarySequence, IncompleteSegmentBehavior behavior = IncompleteSegmentBehavior.Skip)
{
var segmentSize = sizeof(byte) * 8;
var sequenceLength = binarySequence.Length;
var numberOfBytes = (int)Math.Ceiling((double)sequenceLength / segmentSize);
var bytes = new byte[numberOfBytes];
for (int i = 0; i < numberOfBytes; i++)
{
var charactersLeft = sequenceLength - i * segmentSize;
var segmentLength = (charactersLeft < segmentSize ? charactersLeft : segmentSize);
var segment = binarySequence.Substring(i * segmentSize, segmentLength);
if (charactersLeft < segmentSize)
{
segment = HandleIncompleteSegment(segment, segmentSize, behavior);
if (segment == null)
continue;
}
bytes[i] = ConvertBinstrToByte(segment);
}
return bytes;
}
}
This code passes these assertions.
var bytes = new binaryTranslate()
.ConvertBinstrToBytes("00000000");
Assert.Equal(bytes.Length, 1);
Assert.Equal(bytes[0], 0b00000000);
bytes = new binaryTranslate()
.ConvertBinstrToBytes("10000000");
Assert.Equal(bytes.Length, 1);
Assert.Equal(bytes[0], 0b10000000);
bytes = new binaryTranslate()
.ConvertBinstrToBytes("11111111");
Assert.Equal(bytes.Length, 1);
Assert.Equal(bytes[0], 0b11111111);
bytes = new binaryTranslate()
.ConvertBinstrToBytes("00000001");
Assert.Equal(bytes.Length, 1);
Assert.Equal(bytes[0], 0b00000001);
bytes = new binaryTranslate()
.ConvertBinstrToBytes("1100110000110011");
Assert.Equal(bytes.Length, 2);
Assert.Equal(bytes[0], 0b11001100);
Assert.Equal(bytes[1], 0b00110011);
If you are really converting to a string the code should look like this
namespace binaryTranslate
{
class Program
{
static void Main(string[] args)
{
//convertBin("01001000 01100001 01101100 01101100 01101111 00100001");
string results = BinaryTranslate.convertBin(new byte[] { 0x44, 0x61, 0x6c, 0x6c, 0x6f, 0x21 });
}
}
public class BinaryTranslate
{
public static string convertBin(byte[] CodeInput)
{
return string.Join("", CodeInput.Select(x => x.ToString("X2")));
}
}
}
this should do the trick.
public static string FromBinary(string binary)
{
int WordLength = 8;
binary = binary.Replace(' ', '');
while(binary.Length % WordLength != 0)
binary += "0";
string output = String.Empty;
string word = String.Empty;
int offset = 0;
while(offset < binary.Length)
{
int tmp = 0;
word = binary.Substring(offset, 8);
for(int i=0; i<(WordLength - 1); i++)
if(word[i] == '1')
tmp += (int) Math.Pow(2, i);
output += Convert.ToChar(tmp);
offset += WordLength;
}
return output;
}
I've tried open source projects such as this one however it doesn't seem to work at all for me. I then attempted to write my own algorithm like so (tolerance isn't being used yet).
public static Rectangle ImageSearch(Bitmap ToSearch, Bitmap ToFind, int Tolerance, double MinPercent) {
Rectangle ReturnValue = Rectangle.Empty;
BitmapData ToSearchData = ToSearch.LockBits(new Rectangle(0, 0, ToSearch.Width, ToSearch.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData ToFindData = ToFind.LockBits(new Rectangle(0, 0, ToFind.Width, ToFind.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
IntPtr ToSearchScan0 = ToSearchData.Scan0;
IntPtr ToFindScan0 = ToFindData.Scan0;
int PixelWidth = 3; // 3 since 24 bits per pixel format
int ToSearchStride = ToSearchData.Stride;
int ToSearchPadding = ToSearchStride - (ToSearch.Width * PixelWidth);
int ToFindStride = ToFindData.Stride;
int ToFindPadding = ToFindStride - (ToFind.Width * PixelWidth);
unsafe {
byte *ToSearchPixelArray = (byte*)(void*)ToSearchData.Scan0;
byte *ToFindPixelArray = (byte*)(void*)ToFindData.Scan0;
byte sB, sG, sR, fB, fG, fR;
fB = ToFindPixelArray[0];
fG = ToFindPixelArray[1];
fR = ToFindPixelArray[2];
for (int sY = 0; sY < ToSearch.Height; sY++) {
for (int sX = 0; sX < ToSearch.Width * PixelWidth; sX += PixelWidth) {
sB = ToSearchPixelArray[0];
sG = ToSearchPixelArray[1];
sR = ToSearchPixelArray[2];
if (sB == fB && sG == fG && sR == fR) {
Console.WriteLine("found possible match");
byte *ToSearchBackup = ToSearchPixelArray;
byte *ToFindBackup = ToFindPixelArray;
int MatchedPixels = 0;
for (int fY = 0; fY < ToFind.Height; fY++) {
for (int fX = 0; fX < ToFind.Width * PixelWidth; fX += PixelWidth) {
fB = ToFindPixelArray[0];
fG = ToFindPixelArray[1];
fR = ToFindPixelArray[2];
sB = ToSearchPixelArray[0];
sG = ToSearchPixelArray[1];
sR = ToSearchPixelArray[2];
if (sB == fB && sG == fG && sR == fR) {
++MatchedPixels;
} else {
ToSearchPixelArray = ToSearchBackup;
ToFindPixelArray = ToFindBackup;
// this is the best way to break a nested loop in C#
fX = int.MaxValue;
fY = int.MaxValue;
}
}
ToSearchPixelArray += ToSearchStride - sX;
ToFindPixelArray += ToFindPadding;
}
if (MatchedPixels / (ToFind.Width * ToFind.Height) >= MinPercent) {
ReturnValue.X = (int)(sX / 3);
ReturnValue.Y = sY;
ReturnValue.Width = ToFind.Width;
ReturnValue.Height = ToFind.Height;
// this is the best way to break a nested loop in C#
sX = int.MaxValue;
sY = int.MaxValue;
}
}
}
ToSearchPixelArray += ToSearchPadding;
}
}
ToSearch.UnlockBits(ToSearchData);
ToFind.UnlockBits(ToFindData);
return ReturnValue;
}
But not even this will detect a screenshot I take of the exact image I'm searching through. Please do not suggest things such as Emgu, I'm using this in a commercial application and cannot afford to purchase a license from any GNU licensed projects (I'm not open sourcing the project either).
Serching many entries "serchingBitmap" in "sourceBitmap".
In this one I don't using unsafe code.
public static List<Point> FindBitmapsEntry(Bitmap sourceBitmap, Bitmap serchingBitmap)
{
#region Arguments check
if (sourceBitmap == null || serchingBitmap == null)
throw new ArgumentNullException();
if (sourceBitmap.PixelFormat != serchingBitmap.PixelFormat)
throw new ArgumentException("Pixel formats arn't equal");
if (sourceBitmap.Width < serchingBitmap.Width || sourceBitmap.Height < serchingBitmap.Height)
throw new ArgumentException("Size of serchingBitmap bigger then sourceBitmap");
#endregion
var pixelFormatSize = Image.GetPixelFormatSize(sourceBitmap.PixelFormat)/8;
// Copy sourceBitmap to byte array
var sourceBitmapData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
ImageLockMode.ReadOnly, sourceBitmap.PixelFormat);
var sourceBitmapBytesLength = sourceBitmapData.Stride * sourceBitmap.Height;
var sourceBytes = new byte[sourceBitmapBytesLength];
Marshal.Copy(sourceBitmapData.Scan0, sourceBytes, 0, sourceBitmapBytesLength);
sourceBitmap.UnlockBits(sourceBitmapData);
// Copy serchingBitmap to byte array
var serchingBitmapData =
serchingBitmap.LockBits(new Rectangle(0, 0, serchingBitmap.Width, serchingBitmap.Height),
ImageLockMode.ReadOnly, serchingBitmap.PixelFormat);
var serchingBitmapBytesLength = serchingBitmapData.Stride * serchingBitmap.Height;
var serchingBytes = new byte[serchingBitmapBytesLength];
Marshal.Copy(serchingBitmapData.Scan0, serchingBytes, 0, serchingBitmapBytesLength);
serchingBitmap.UnlockBits(serchingBitmapData);
var pointsList = new List<Point>();
// Serching entries
// minimazing serching zone
// sourceBitmap.Height - serchingBitmap.Height + 1
for (var mainY = 0; mainY < sourceBitmap.Height - serchingBitmap.Height + 1; mainY++)
{
var sourceY = mainY * sourceBitmapData.Stride;
for (var mainX = 0; mainX < sourceBitmap.Width - serchingBitmap.Width + 1; mainX++)
{// mainY & mainX - pixel coordinates of sourceBitmap
// sourceY + sourceX = pointer in array sourceBitmap bytes
var sourceX = mainX*pixelFormatSize;
var isEqual = true;
for (var c = 0; c < pixelFormatSize; c++)
{// through the bytes in pixel
if (sourceBytes[sourceX + sourceY + c] == serchingBytes[c])
continue;
isEqual = false;
break;
}
if (!isEqual) continue;
var isStop = false;
// find fist equalation and now we go deeper)
for (var secY = 0; secY < serchingBitmap.Height; secY++)
{
var serchY = secY * serchingBitmapData.Stride;
var sourceSecY = (mainY + secY)*sourceBitmapData.Stride;
for (var secX = 0; secX < serchingBitmap.Width; secX++)
{// secX & secY - coordinates of serchingBitmap
// serchX + serchY = pointer in array serchingBitmap bytes
var serchX = secX*pixelFormatSize;
var sourceSecX = (mainX + secX)*pixelFormatSize;
for (var c = 0; c < pixelFormatSize; c++)
{// through the bytes in pixel
if (sourceBytes[sourceSecX + sourceSecY + c] == serchingBytes[serchX + serchY + c]) continue;
// not equal - abort iteration
isStop = true;
break;
}
if (isStop) break;
}
if (isStop) break;
}
if (!isStop)
{// serching bitmap is founded!!
pointsList.Add(new Point(mainX, mainY));
}
}
}
return pointsList;
}
It doesn't work accurately for me but it does give me an idea. I think the problem with this soludion is that it is looking for an exact pixel-for-pixel instance. Basically I am doing what you are doing, trying to find 1 or more occurrences of a bitmap in another but the properties may vary like brightness, contrast, size, etc. I have tired several things including Aforge.Net and Accord.Net but I can't seem to get an acceptable accuracy > 50%. Thanks for posting.
I am having an issue trying to port the following code from C to C#. not having much success with using the fixed keyword and a ptr that gets reassigned. Could someone tell me how to represent the following code in c#?
p = &table[(i = start[k]) >> m];
i <<= tablebits;
n = k - tablebits;
/* make tree (n length) */
while (--n >= 0) {
if (*p == 0) {
right[avail] = left[avail] = 0;
*p = avail++;
}
if (i & 0x8000) p = &right[*p];
else p = &left[*p];
i <<= 1;
}
*p = j;
Here goes using no pointers (C# safe)...
var[] curtable = table;
i = start[k];
int idx = i >> m;
i <<= tablebits;
n = k - tablebits;
/* make tree (n length) */
while (--n >= 0)
{
if (curtable[idx] == 0)
{
right[avail] = left[avail] = 0;
curtable[idx] = avail++;
}
if (i & 0x8000)
{
idx = curtable[idx];
curtable = right;
}
else
{
idx = curtable[idx];
curtable = left;
}
i <<= 1;
}
curtable[idx] = j;
Looks like I was able to resolve the issue by using fixed pointers for each of the tables, then a changable ptr that I can assign the appropriate fixed pointer to. compiles fine and code appears to operate with the same result as the c code.
fixed(ushort* p = &table[(i = start[k]) >> m])
{
ushort* p4 = p;
i <<= tablebits;
n = k - tablebits;
/* make tree (n length) */
while (--n >= 0)
{
if (*p == 0)
{
right[avail] = left[avail] = 0;
*p = (ushort)avail++;
}
if ((i & 0x8000) > 0) fixed(ushort* p2 = &right[*p4]) {p4 = p2;}
else fixed (ushort* p3 = &left[*p4]) { p4 = p3; }
i <<= 1;
}
*p4 = (ushort)j;
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have designed a forms app which could have been better designed for unit testing by using business logic etc but at this stage I do not want to alter my code. It is an app which performs steganography whereby a message is embedded in an image using an LSB algorithm. I am currently trying to write a unit test for the button2 click event. When button2 is pressed; it will take text from two other textboxes and an image from a picturebox and run the LSB algorithm. Below is the test function. I create test values for the textboxes concerned. When I run the test I get: System.NullReferenceException: Object reference not set to an instance of an object. Does this refer to the object sender = null; EventArgs e = null;. Or is what I am doing even possible? Do I have to resort to NUnitForms? I have added button2_click after the test function:
public void button2_ClickTest()
{
StegApp_Accessor target = new StegApp_Accessor();
// TODO: Initialize to an appropriate value
object sender = null; // TODO: Initialize to an appropriate value
EventArgs e = null; // TODO: Initialize to an appropriate value
target.textBox4.Text = "123456";
target.textBox5.Text = "test message";
target.button2_Click(sender, e);
//Assert.Inconclusive("A method that does not return a value cannot
// be verified.");
//target.textBox4.Text = "123456";
//target.textBox5.Text = "test message";
/*
if (target.textBox4.Text.Length > 6 || target.textBox4.Text.Length < 0)
{
Assert.Fail("Key is out of range");
}*/
//Assert.IsInstanceOfType(target.b1,typeof(byte[]));
if(target.b1.Length != target.temp4.Length)
{
Assert.Fail("B1 array does not have the correct lenght");
}
Assert.IsInstanceOfType(target.image1,typeof(Bitmap));
Assert.IsInstanceOfType(target.sb,typeof(StringBuilder));
if(target.sb.Length != target.tmp3.Length)
{
Assert.Fail("Issue with Stringbuilder sb. Lenght not equal to 'tmp3'!");
}
Assert.Equals(target.z,target.StringLenght);
Assert.Equals(target.c, target.textBox5.Text.Length);
}
`private void button2_Click(object sender, EventArgs e)
{
//int x1, y1, z = 0;
try
{
// Convert String Into Byte Array
//byte[] sourceData = System.Text.ASCIIEncoding.ASCII.GetBytes(a);
// Convert Each Byte Into A Binary String
//foreach (byte thisByte in sourceData)
// binaryString.Append(Convert.ToString(thisByte, 2));
while (!key)
{
if (textBox4.Text == "")
{
//b1 = ASCIIEncoding.ASCII.GetBytes(textBox5.Text);
key = false;
MessageBox.Show("Error, enter your six digit key!");
return;
}
else if (textBox4.Text.Length > 6)
{
MessageBox.Show("Error, Key too long, try again!");
return;
}
else
{
//temp4 = textBox4.Text[0] + textBox4.Text[1] + textBox4.Text[2] + textBox4.Text[3] + textBox4.Text[4] + textBox4.Text[5] + textBox5.Text;
c = textBox5.Text.Length;
temp5 = c.ToString();
if (c <= 9)
{
temp5 = "000" + temp5;
}
else if (c <= 99)
{
temp5 = "00" + temp5;
}
else if (c <= 999)
{
temp5 = "0" + temp5;
}
else if (c <= 9999)
{
}
else
{
MessageBox.Show("Message too long for this tool,try again");
return;
}
temp4 = textBox4.Text + temp5 + textBox5.Text;
b1 = ASCIIEncoding.ASCII.GetBytes(temp4);
key = true;
}
}
//byte[] b1 = ASCIIEncoding.ASCII.GetBytes(textBox5.Text);
//b1 = Encoding.Unicode.GetBytes(a);
//Create the array to be returned.
tmp2 = new string[b1.Length];
//Interate through each byte
for (int i = 0; i < b1.Length; i++)
{
int x = b1[i];
tmp = "";
while (true)
{
if ((x % 2) == 1)
{
tmp = "1" + tmp;
}
else
{
tmp = "0" + tmp;
}
x /= 2;
if (x < 1) break;
}
//Make sure the value is 8 chars long.
tmp2[i] = tmp.PadLeft(8, '0');
}
//string a="";
for (int i = 0; i < b1.Length; i++)
{
//a = tmp2[i];
tmp3 = tmp3 + tmp2[i];
}
if (key)
{
tmp3 = "00" + tmp3;
}
else
{
tmp3 = "10" + tmp3;
}
sb.Append(tmp3);
//temp5 = c.ToString();
//z= c+1;
StringLenght = sb.Length;
byte Mask0 = 254;
byte Mask1 = 1;
byte NewRed = 0, NewGreen = 0, NewBlue = 0;
// Loop through the images pixels to reset color.
for (x1 = 0, y1 = 0; x1 < image1.Width && z < StringLenght; x1++)
{
for (y1 = 0; y1 < image1.Height && z < StringLenght; y1++)
{
Color pixelColor = image1.GetPixel(x1, y1);
//byte NewRed, NewGreen, NewBlue;
if (sb[z] == '0')
{
NewRed = Convert.ToByte(pixelColor.R & Mask0);
Color newColor = Color.FromArgb(NewRed, pixelColor.G, pixelColor.B);
image1.SetPixel(x1, y1, newColor);
pixelColor = image1.GetPixel(x1, y1);
z++;
if (z == StringLenght)
{
break;
}
}
else
{
NewRed = Convert.ToByte(pixelColor.R | Mask1);
Color newColor = Color.FromArgb(NewRed, pixelColor.G, pixelColor.B);
image1.SetPixel(x1, y1, newColor);
pixelColor = image1.GetPixel(x1, y1);
z++;
if (z == StringLenght)
{
break;
}
}
if (sb[z] == '0')
{
NewGreen = Convert.ToByte(pixelColor.G & Mask0);
Color newColor = Color.FromArgb(pixelColor.R, NewGreen, pixelColor.B);
image1.SetPixel(x1, y1, newColor);
pixelColor = image1.GetPixel(x1, y1);
z++;
if (z == StringLenght)
{
break;
}
}
else
{
NewGreen = Convert.ToByte(pixelColor.G | Mask1);
Color newColor = Color.FromArgb(pixelColor.R, NewGreen, pixelColor.B);
image1.SetPixel(x1, y1, newColor);
pixelColor = image1.GetPixel(x1, y1);
z++;
if (z == StringLenght)
{
break;
}
}
if (sb[z] == '0')
{
NewBlue = Convert.ToByte(pixelColor.B & Mask0);
Color newColor = Color.FromArgb(pixelColor.R, pixelColor.G, NewBlue);
image1.SetPixel(x1, y1, newColor);
pixelColor = image1.GetPixel(x1, y1);
z++;
if (z == StringLenght)
{
break;
}
}
else
{
NewBlue = Convert.ToByte(pixelColor.B | Mask1);
Color newColor = Color.FromArgb(pixelColor.R, pixelColor.G, NewBlue);
image1.SetPixel(x1, y1, newColor);
pixelColor = image1.GetPixel(x1, y1);
z++;
if (z == StringLenght)
{
break;
}
}
//string binary1 = Convert.ToString(pixelColor.R, 2);
//char last1 = binary1[binary1.Length - 1];
}
}
MessageBox.Show("Message embedded");
//Color newColor = Color.FromArgb(NewRed, NewGreen, NewBlue);
//image1.SetPixel(x, y, newColor);
// Set the PictureBox to display the image.
//pictureBox1.Image = image1;
// Display the pixel format in Label1.
//label1.Text = "Pixel format: " + image1.PixelFormat.ToString();
}
catch (ArgumentException)
{
MessageBox.Show("There was an error." +
"Check the path to the image file.");
}
//pictureBox2.Image = image1;
//Byte[] buf = Encoding.Unicode.GetBytes(RetreivedMessage.ToString());
//Byte[] buf = Encoding.Unicode.GetBytes(RetreivedMessage.ToString());
//string result = System.Text.Encoding.Unicode.GetString(buf);
//String result = Encoding.Unicode.GetString(buf);
//StringBuilder r2 = new StringBuilder();
//foreach (Byte b in Encoding.Unicode.GetBytes(FinalRetreivedMessage))
//{
// r2.Append(Convert.ToString(b));
// }
//int v = 0;
//for (int i = 0; i < FinalRetreivedMessage.Length; i++)
// {
// v = v * 2 + (FinalRetreivedMessage[i] == '0' ? 0 : 1);
// }
//string result = v.ToString();
// copy the string as UTF-8 bytes.
// byte[] utf8Bytes = new byte[FinalRetreivedMessage.Length];
// for (int i = 0; i < FinalRetreivedMessage.Length; ++i)
// {
//Debug.Assert( 0 <= utf8String[i] && utf8String[i] <= 255, "the char must be in byte's range");
// utf8Bytes[i] = (byte)FinalRetreivedMessage[i];
// }
//Encoding.UTF8.GetString(utf8Bytes, 0, utf8Bytes.Length);
// utf8Bytes = new byte[]{1,1,1,0,1,0,0,0};
// string result1 = Encoding.UTF8.GetString(utf8Bytes, 0, utf8Bytes.Length);
//string result1 = Encoding.UTF8.GetString(utf8Bytes);
// UTF8Encoding enc = new UTF8Encoding();
// string str = enc.GetString(utf8Bytes);
// Byte[] encodedBytes = enc.GetBytes(FinalRetreivedMessage);
// string message = encodedBytes.ToString();
// int count = FinalRetreivedMessage.Length / 8;
// var bollox = new byte[count];
// for (int i = 0; i < count; i++)
// bollox[i] = Convert.ToByte(FinalRetreivedMessage.Substring(i * 8, 8), 2);
// var bollox1 = new byte[count];
//for (int i = 0; i < count; i++)
//bollox1[i] = Encoding.Unicode.GetBytes(FinalRetreivedMessage.Substring(i * 8, 8));
// string result2 = bollox.ToString();
// string result3 = enc.GetString(bollox);
// string result4 = System.Convert.ToString(bollox);
// string StringIWant = BitConverter.ToString(bollox);
// string result5 = BitConverter.ToString(encodedBytes);
// string result6 = BitConverter.ToString(utf8Bytes);
// string result7 = BitConverter.ToString(Encoding.Unicode.GetBytes(FinalRetreivedMessage));
// string result8 = System.Convert.ToString(Encoding.Unicode.GetBytes(FinalRetreivedMessage));
// string result9 = Encoding.Unicode.GetString(Encoding.Unicode.GetBytes(FinalRetreivedMessage));
// string result10 = Encoding.Default.GetString(Encoding.Unicode.GetBytes(FinalRetreivedMessage));
}`
private void button2_Click(object sender, EventArgs e)
{
Embed();
}
public void Embed(string Embedkey, string EmbedMessage,Bitmap image3)
{
// embed message in image
}
public void EmbedTest()
{
StegApp target = new StegApp(); // TODO: Initialize to an appropriate value
string Embedkey = "123456"; // TODO: Initialize to an appropriate value
string EmbedMessage = "test2"; // TODO: Initialize to an appropriate value
Bitmap image3 = null; // TODO: Initialize to an appropriate value
image3 = new Bitmap(#"C:\Users\Admin\Documents\dt265\Project\Sky\sky-and-cloud.bmp",true);
string a="123456",b="test2";
target.Embed(Embedkey, EmbedMessage, image3);
//Assert.Inconclusive("A method that does not return a value cannot be verified.");
if (Embedkey.Length > 6 || Embedkey.Length < 0)
{
Assert.Fail("Key is out of range");
}
//Assert.IsInstanceOfType(target.b1,typeof(byte[]));
if(target.b1.Length != target.temp4.Length)
{
Assert.Fail("B1 array does not have the correct lenght");
}
Assert.IsInstanceOfType(target.image1,typeof(Bitmap));
Assert.IsInstanceOfType(target.sb,typeof(StringBuilder));
if(target.sb.Length != target.tmp3.Length)
{
Assert.Fail("Issue with Stringbuilder sb. Lenght not equal to 'tmp3'!");
}
if(target.z != target.StringLenght)
{
Assert.Fail("z != StringLenght");
}
if (target.c != EmbedMessage.Length)
{
Assert.Fail("c is not the lenght of the Message!");
}
}