package qrcode;
import java.util.ArrayList;
import java.util.List;
import org.opencv.core.Mat;
public class FinderPatternFinder {
Mat src;
FinderPatternFinder(Mat srcOri){
src = srcOri;
}
List<FinderPattern> possibleCenters=new ArrayList<FinderPattern>();
int crossCheckStateCount[]=new int[5];
void find() {
int maxI = src.rows();
int maxJ = src.cols();
int iSkip = 1;
int stateCount[]=new int[5];
// for(int i=iSkip-1;i<maxI;i +=iSkip){//遍历行
for(int i=0;i<maxI;i++){
stateCount[0]=stateCount[1]=stateCount[2]
=stateCount[3]=stateCount[4]=0;
int currentState=0;
for(int j=0;j<maxJ;j++){//遍历列
double[] data1 = null;
data1=src.get(i, j);
if(data1[0]==0){//像素值为0,因为传入的Src为二值图
if((currentState%2)==1){
currentState++;
}
stateCount[currentState]++;
}else {
if((currentState%2)==0){
if(currentState==4){
if(foundPatternCross(stateCount)){
boolean confirmed = handlePossibleCenter(stateCount, i, j);
if (confirmed) {
// Start examining every other line. Checking each line turned out to be too
// expensive and didn't improve performance.
iSkip = 1;
} else {
stateCount[0] = stateCount[2];
stateCount[1] = stateCount[3];
stateCount[2] = stateCount[4];
stateCount[3] = 1;
stateCount[4] = 0;
currentState = 3;
continue;
}
//做清空操作,再次查找
currentState = 0;
stateCount[0] = 0;
stateCount[1] = 0;
stateCount[2] = 0;
stateCount[3] = 0;
stateCount[4] = 0;
} else { // 移位计数为2
stateCount[0] = stateCount[2];
stateCount[1] = stateCount[3];
stateCount[2] = stateCount[4];
stateCount[3] = 1;
stateCount[4] = 0;
currentState = 3;
}
}else{
stateCount[++currentState]++;
}
}else{
stateCount[currentState]++;
}
}
}
}
}
boolean foundPatternCross(int[] stateCount) {
int totalModuleSize = 0;
for (int i = 0; i < 5; i++) {
int count = stateCount[i];
if (count == 0) {
return false;
}
totalModuleSize += count;
}
if (totalModuleSize < 7) {
return false;
}
float moduleSize = totalModuleSize / 7.0f;
float maxVariance = moduleSize / 2.0f;
// Allow less than 50% variance from 1-1-3-1-1 proportions
return
Math.abs(moduleSize - stateCount[0]) < maxVariance &&
Math.abs(moduleSize - stateCount[1]) < maxVariance &&
Math.abs(3.0f * moduleSize - stateCount[2]) < 3 * maxVariance &&
Math.abs(moduleSize - stateCount[3]) < maxVariance &&
Math.abs(moduleSize - stateCount[4]) < maxVariance;
}
boolean handlePossibleCenter(int []stateCount,int i,int j) {
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] +stateCount[4];
float centerJ = centerFromEnd(stateCount, j);
float centerI = crossCheckVertical(i, (int) centerJ, stateCount[2], stateCountTotal);
if (centerI>=0) {
// Re-cross check
centerJ = crossCheckHorizontal((int) centerJ, (int) centerI, stateCount[2], stateCountTotal);
if (centerJ>=0 &&
(true || crossCheckDiagonal((int) centerI, (int) centerJ, stateCount[2], stateCountTotal))) {
float estimatedModuleSize = stateCountTotal / 7.0f;
boolean found = false;
for (int index = 0; index < possibleCenters.size(); index++) {
FinderPattern center = possibleCenters.get(index);
// Look for about the same center and module size:
if (center.aboutEquals(estimatedModuleSize, centerI, centerJ)) {
FinderPattern currcenter=possibleCenters.get(index);
currcenter.combineEstimate(centerI, centerJ, estimatedModuleSize);
found = true;
break;
}
}
if (!found) {
FinderPattern point=new FinderPattern(centerJ, centerI, estimatedModuleSize,1);
possibleCenters.add(point);
}
return true;
}
}
return false;
}
float centerFromEnd(int[] stateCount, int end) {
return (end - stateCount[4] - stateCount[3]) - stateCount[2] / 2.0f;
}
float crossCheckVertical(int startI,int cneterJ,int maxCount,int originalStateCountTotal ) {
int maxI = src.rows();
crossCheckStateCount[0]=0;
crossCheckStateCount[1]=0;
crossCheckStateCount[2]=0;
crossCheckStateCount[3]=0;
crossCheckStateCount[4]=0;
int i = startI;
while (i >= 0 && src.get(i,cneterJ)[0]==0) {
crossCheckStateCount[2]++;
i--;
}
if (i < 0) {
return -1;
}
while (i >= 0 && src.get(i,cneterJ)[0]>0 && crossCheckStateCount[1] <= maxCount) {
crossCheckStateCount[1]++;
i--;
}
// If already too many modules in this state or ran off the edge:
if (i < 0 || crossCheckStateCount[1] > maxCount) {
return -1;
}
while (i >= 0 && src.get(i,cneterJ)[0]==0 && crossCheckStateCount[0] <= maxCount) {
crossCheckStateCount[0]++;
i--;
}
if (crossCheckStateCount[0] > maxCount) {
return -1;
}
// Now also count down from center
i = startI + 1;
while (i < maxI && src.get(i,cneterJ)[0]==0) {
crossCheckStateCount[2]++;
i++;
}
if (i == maxI) {
return -1;
}
while (i < maxI && src.get(i,cneterJ)[0]>0 && crossCheckStateCount[3] < maxCount) {
crossCheckStateCount[3]++;
i++;
}
if (i == maxI || crossCheckStateCount[3] >= maxCount) {
return -1;
}
while (i < maxI && src.get(i,cneterJ)[0]==0 && crossCheckStateCount[4] < maxCount) {
crossCheckStateCount[4]++;
i++;
}
if (crossCheckStateCount[4] >= maxCount) {
return -1;
}
// If we found a finder-pattern-like section, but its size is more than 40% different than
// the original, assume it's a false positive
int stateCountTotal = crossCheckStateCount[0] + crossCheckStateCount[1] + crossCheckStateCount[2] + crossCheckStateCount[3] +
crossCheckStateCount[4];
if (5 * Math.abs(stateCountTotal - orig
没有合适的资源?快使用搜索试试~ 我知道了~
Java语言基于OpenCV实现二维码的检测定位.zip
共5个文件
java:5个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 180 浏览量
2024-05-01
21:06:28
上传
评论
收藏 9KB ZIP 举报
温馨提示
Java语言基于OpenCV实现二维码的检测定位
资源推荐
资源详情
资源评论
收起资源包目录
Java语言基于OpenCV实现二维码的检测定位.zip (5个子文件)
QR_Code_Positioin-JAVA-master
src
FinderPatternFinder.java 14KB
ImageViewer.java 3KB
Detector.java 7KB
FinderPattern.java 1KB
Main.java 2KB
共 5 条
- 1
资源评论
我慢慢地也过来了
- 粉丝: 6282
- 资源: 3956
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功