/// <summary> <p>This is called when a horizontal scan finds a possible alignment pattern. It will /// cross check with a vertical scan, and if successful, will see if this pattern had been /// found on a previous horizontal scan. If so, we consider it confirmed and conclude we have /// found the alignment pattern.</p> /// /// </summary> /// <param name="stateCount">reading state module counts from horizontal scan /// </param> /// <param name="i">row where alignment pattern may be found /// </param> /// <param name="j">end of possible alignment pattern in row /// </param> /// <returns> {@link AlignmentPattern} if we have found the same pattern twice, or null if not /// </returns> private AlignmentPattern handlePossibleCenter(int[] stateCount, int i, int j) { int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2]; NullableFloat centerJ = centerFromEnd(stateCount, j); if (centerJ == null) { return(null); } NullableFloat centerI = crossCheckVertical(i, (int)centerJ.Value, 2 * stateCount[1], stateCountTotal); if (centerI != null) { float estimatedModuleSize = (stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f; foreach (AlignmentPattern center in possibleCenters) { // Look for about the same center and module size: if (center.aboutEquals(estimatedModuleSize, centerI.Value, centerJ.Value)) { return(center.combineEstimate(centerI.Value, centerJ.Value, estimatedModuleSize)); } } // Hadn't found this before; save it var point = new AlignmentPattern(centerJ.Value, centerI.Value, estimatedModuleSize); possibleCenters.Add(point); if (resultPointCallback != null) { resultPointCallback(point); } } return(null); }
public void TestRoundtripNullableFloat([ValueSource(nameof(NullableFloatValues))] float?value) { var obj = new NullableFloat { Value = value }; var actualObj = Roundtrip(obj); actualObj.Should().NotBeNull(); actualObj.Value.Should().Be(value); }
/// <summary> <p>This is called when a horizontal scan finds a possible alignment pattern. It will /// cross check with a vertical scan, and if successful, will, ah, cross-cross-check /// with another horizontal scan. This is needed primarily to locate the real horizontal /// center of the pattern in cases of extreme skew.</p> /// /// If that succeeds the finder pattern location is added to a list that tracks /// the number of times each location has been nearly-matched as a finder pattern. /// Each additional find is more evidence that the location is in fact a finder /// pattern center /// /// </summary> /// <param name="stateCount">reading state module counts from horizontal scan /// </param> /// <param name="i">row where finder pattern may be found /// </param> /// <param name="j">end of possible finder pattern in row /// </param> /// <returns> true if a finder pattern candidate was found this time /// </returns> protected bool handlePossibleCenter(int[] stateCount, int i, int j) { int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4]; NullableFloat centerJ = centerFromEnd(stateCount, j); if (centerJ == null) { return(false); } NullableFloat centerI = crossCheckVertical(i, (int)centerJ.Value, stateCount[2], stateCountTotal); if (centerI != null) { // Re-cross check centerJ = crossCheckHorizontal((int)centerJ.Value, (int)centerI.Value, stateCount[2], stateCountTotal); if (centerJ != null) { float estimatedModuleSize = stateCountTotal / 7.0f; bool found = false; for (int index = 0; index < possibleCenters.Count; index++) { var center = (FinderPattern)possibleCenters[index]; // Look for about the same center and module size: if (center.aboutEquals(estimatedModuleSize, centerI.Value, centerJ.Value)) { possibleCenters.RemoveAt(index); possibleCenters.Insert(index, center.combineEstimate(centerI.Value, centerJ.Value, estimatedModuleSize)); found = true; break; } } if (!found) { var point = new FinderPattern(centerJ.Value, centerI.Value, estimatedModuleSize); possibleCenters.Add(point); if (resultPointCallback != null) { resultPointCallback(point); } } return(true); } } return(false); }