こんにちは現在、AVFoundationフレームワークを使用してカード画像を正常にキャプチャできるOCR読み取りアプリに取り組んでいます。
次のステップでは、カードのエッジを見つける必要があります。これにより、メインのキャプチャ画像からカード画像をトリミングし、後で処理のために OCR エンジンに送信できます。
主な問題は、カードの端を見つけることです。この目的のために OpenCV を使用する以下のコード (別のオープン ソース プロジェクトから取得) を使用しています。カードが純粋な長方形のカードまたは紙の場合、正常に動作します。しかし、角が丸いカード(運転免許証など)を使用すると、検出に失敗します。また、私は OpenCV の専門知識があまりありません。この問題の解決に役立つ人はいますか?
- (void)detectEdges
{
cv::Mat original = [MAOpenCV cvMatFromUIImage:_adjustedImage];
CGSize targetSize = _sourceImageView.contentSize;
cv::resize(original, original, cvSize(targetSize.width, targetSize.height));
cv::vector<cv::vector<cv::Point>>squares;
cv::vector<cv::Point> largest_square;
find_squares(original, squares);
find_largest_square(squares, largest_square);
if (largest_square.size() == 4)
{
// Manually sorting points, needs major improvement. Sorry.
NSMutableArray *points = [NSMutableArray array];
NSMutableDictionary *sortedPoints = [NSMutableDictionary dictionary];
for (int i = 0; i < 4; i++)
{
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithCGPoint:CGPointMake(largest_square[i].x, largest_square[i].y)], @"point" , [NSNumber numberWithInt:(largest_square[i].x + largest_square[i].y)], @"value", nil];
[points addObject:dict];
}
int min = [[points valueForKeyPath:@"@min.value"] intValue];
int max = [[points valueForKeyPath:@"@max.value"] intValue];
int minIndex;
int maxIndex;
int missingIndexOne;
int missingIndexTwo;
for (int i = 0; i < 4; i++)
{
NSDictionary *dict = [points objectAtIndex:i];
if ([[dict objectForKey:@"value"] intValue] == min)
{
[sortedPoints setObject:[dict objectForKey:@"point"] forKey:@"0"];
minIndex = i;
continue;
}
if ([[dict objectForKey:@"value"] intValue] == max)
{
[sortedPoints setObject:[dict objectForKey:@"point"] forKey:@"2"];
maxIndex = i;
continue;
}
NSLog(@"MSSSING %i", i);
missingIndexOne = i;
}
for (int i = 0; i < 4; i++)
{
if (missingIndexOne != i && minIndex != i && maxIndex != i)
{
missingIndexTwo = i;
}
}
if (largest_square[missingIndexOne].x < largest_square[missingIndexTwo].x)
{
//2nd Point Found
[sortedPoints setObject:[[points objectAtIndex:missingIndexOne] objectForKey:@"point"] forKey:@"3"];
[sortedPoints setObject:[[points objectAtIndex:missingIndexTwo] objectForKey:@"point"] forKey:@"1"];
}
else
{
//4rd Point Found
[sortedPoints setObject:[[points objectAtIndex:missingIndexOne] objectForKey:@"point"] forKey:@"1"];
[sortedPoints setObject:[[points objectAtIndex:missingIndexTwo] objectForKey:@"point"] forKey:@"3"];
}
[_adjustRect topLeftCornerToCGPoint:[(NSValue *)[sortedPoints objectForKey:@"0"] CGPointValue]];
[_adjustRect topRightCornerToCGPoint:[(NSValue *)[sortedPoints objectForKey:@"1"] CGPointValue]];
[_adjustRect bottomRightCornerToCGPoint:[(NSValue *)[sortedPoints objectForKey:@"2"] CGPointValue]];
[_adjustRect bottomLeftCornerToCGPoint:[(NSValue *)[sortedPoints objectForKey:@"3"] CGPointValue]];
}
original.release();
}