110,539
社区成员
发帖
与我相关
我的任务
分享
Bitmap temp = source.Clone() as Bitmap; // 复制原始图像
FiltersSequence seq = new FiltersSequence();
seq.Add(Grayscale.CommonAlgorithms.BT709); // 添加灰度滤镜
seq.Add(new OtsuThreshold()); // 添加二值化滤镜
temp = seq.Apply(source); // 应用滤镜
// 从图像中提取宽度和高度大于150的blob
BlobCounter extractor = new BlobCounter();
extractor.FilterBlobs = true;
extractor.MinWidth = extractor.MinHeight = 150;
extractor.MaxWidth = extractor.MaxHeight = 350;
extractor.ProcessImage(temp);
foreach (Blob blob in extractor.GetObjectsInformation())
{
// 获取扑克牌的边缘点
List< IntPoint > edgePoints = extractor.GetBlobsEdgePoints(blob);
// 利用边缘点,在原始图像上找到四角
List< IntPoint > corners = PointsCloud.FindQuadrilateralCorners(edgePoints);
}
// 用于从原始图像提取扑克牌
QuadrilateralTransformation quadTransformer = new QuadrilateralTransformation();
// 用于调整扑克牌大小
ResizeBilinear resizer = new ResizeBilinear(CardWidth, CardHeight);
foreach (Blob blob in extractor.GetObjectsInformation())
{
// 获取扑克牌边缘点
List<IntPoint> edgePoints = extractor.GetBlobsEdgePoints(blob);
// 利用边缘点,在原始图像上找到四角
List<IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints);
Bitmap cardImg = quadTransformer.Apply(source); // 提取扑克牌图像
if (cardImg.Width > cardImg.Height) // 如果扑克牌横放
cardImg.RotateFlip(RotateFlipType.Rotate90FlipNone); // 旋转之
cardImg = resizer.Apply(cardImg); // 归一化(重设大小)扑克牌
.....
}
public enum Rank
{
NOT_RECOGNIZED = 0,
Ace = 1,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Ten,
Jack,
Queen,
King
}
public enum Suit
{
NOT_RECOGNIZED = 0,
Hearts,
Diamonds,
Spades,
Clubs
}
public class Card
{
// 变量
private Rank rank; // 大小
private Suit suit; // 花色
private Bitmap image; // 提取出的图像
private Point[] corners ;// 四角点
// 属性
public Point[] Corners
{
get { return this.corners; }
}
public Rank Rank
{
set { this.rank = value; }
}
public Suit Suit
{
set { this.suit = value; }
}
public Bitmap Image
{
get { return this.image; }
}
// 构造函数
public Card(Bitmap cardImg, IntPoint[] cornerIntPoints)
{
this.image = cardImg;
// 将AForge.IntPoint数组转化为System.Drawing.Point数组
int total = cornerIntPoints.Length;
corners = new Point[total];
for(int i = 0 ; i < total ; i++)
{
this.corners[i].X = cornerIntPoints[i].X;
this.corners[i].Y = cornerIntPoints[i].Y;
}
}
}
public Bitmap GetTopRightPart()
{
if (image == null)
return null;
Crop crop = new Crop(new Rectangle(image.Width - 37, 10, 30, 60));
return crop.Apply(image);
}
char color = 'B';
// 开始,锁像素
BitmapData imageData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadOnly, bmp.PixelFormat);
int totalRed = 0;
int totalBlack = 0;
unsafe
{
// 统计红与黑
try
{
UnmanagedImage img = new UnmanagedImage(imageData);
int height = img.Height;
int width = img.Width;
int pixelSize = (img.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;
byte* p = (byte*)img.ImageData.ToPointer();
// 逐行
for (int y = 0; y < height; y++)
{
// 逐像素
for (int x = 0; x < width; x++, p += pixelSize)
{
int r = (int)p[RGB.R]; // 红
int g = (int)p[RGB.G]; // 绿
int b = (int)p[RGB.B]; // 蓝
if (r > g + b) // 红 > 绿 + 蓝
totalRed++; // 认为是红色
if (r <= g + b && r < 50 && g < 50 && b < 50) // 红绿蓝均小于50
totalBlack++; // 认为是黑色
}
}
}
finally
{
bmp.UnlockBits(imageData); // 解锁
}
}
if (totalRed > totalBlack) // 红色占优
color = 'R'; // 设置颜色为红,否则默认黑色
return color;
private bool IsFaceCard(Bitmap bmp)
{
FiltersSequence commonSeq = new FiltersSequence();
commonSeq.Add(Grayscale.CommonAlgorithms.BT709);
commonSeq.Add(new BradleyLocalThresholding());
commonSeq.Add(new DifferenceEdgeDetector());
Bitmap temp = this.commonSeq.Apply(bmp);
ExtractBiggestBlob extractor = new ExtractBiggestBlob();
temp = extractor.Apply(temp); // 提取最大图块
if (temp.Width > bmp.Width / 2) // 如果宽度大于整个牌的一般宽
return true; // 人物牌
return false; // 数字牌
}
private Suit ScanSuit(Bitmap suitBmp, char color)
{
Bitmap temp = commonSeq.Apply(suitBmp);
//Extract biggest blob on card
ExtractBiggestBlob extractor = new ExtractBiggestBlob();
temp = extractor.Apply(temp); //Biggest blob is suit blob so extract it
Suit suit = Suit.NOT_RECOGNIZED;
//Determine type of suit according to its color and width
if (color == 'R')
suit = temp.Width >= 55 ? Suit.Diamonds : Suit.Hearts;
if (color == 'B')
suit = temp.Width <= 48 ? Suit.Spades : Suit.Clubs;
return suit;
}