<h5 dir="auto">System information (version)</h5>
<ul dir="auto">
<li>OpenCV =&gt; 3.4.0</li>
<li>Operating System / Platform =&gt; Linux Ubuntu 16.04 X86 64 Bit</li>
<li>Compiler =&gt; gcc 5.4</li>
</ul>
<h5 dir="auto">Detailed description</h5>
<p dir="auto">Running BFmatcher with crossCheck enabled doesn't really cross check. According to the documentation (<a href="https://docs.opencv.org/trunk/d3/da1/classcv_1_1BFMatcher.html#ac6418c6f87e0e12a88979ea57980c020" rel="nofollow">https://docs.opencv.org/trunk/d3/da1/classcv_1_1BFMatcher.html#ac6418c6f87e0e12a88979ea57980c020</a>)</p>
<blockquote>
<p dir="auto">If crossCheck==true, then the knnMatch() method with k=1 will only return pairs (i,j) such that for i-th query descriptor the j-th descriptor in the matcher's collection is the nearest and vice versa, i.e. the BFMatcher will only return consistent pairs.</p>
</blockquote>
<p dir="auto">I read this as, if <em>i</em> is closest to <em>j</em>, then <em>j</em> is also closest to <em>i</em>. I.e. this is symmetrical. However, this does not seem to be the case with the implemented algorithm. Also, if we switch the collections, i.e. queryDescriptors and trainDescriptors, we get different results, which is unexpected.</p>
<h5 dir="auto">Steps to reproduce</h5>
<p dir="auto">To illustrate the first part of the issue, try the following</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import numpy
import cv2

sources = numpy.array([[1, 1, 0], [1, 1, 1]], dtype=numpy.uint8)
targets = numpy.array([[1, 1, 1], [0, 0, 0]], dtype=numpy.uint8)
for si, source in enumerate(sources):
    for ti, target in enumerate(targets):
        print('%d -&gt; %d: %d' % (si, ti, cv2.norm(source, target, cv2.NORM_HAMMING)))

bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.knnMatch(sources, targets, k=1)
print('-- crosscheck=True')
for match in matches:
    if match:
        print('%d -&gt; %d: %f' % (match[0].queryIdx, match[0].trainIdx, match[0].distance))

bf_nocc = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=False)
matches_nocc = bf.knnMatch(sources, targets, k=1)
print('-- crosscheck=False')
for match in matches_nocc:
    if match:
        print('%d -&gt; %d: %f' % (match[0].queryIdx, match[0].trainIdx, match[0].distance))"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">numpy</span>
<span class="pl-k">import</span> <span class="pl-s1">cv2</span>

<span class="pl-s1">sources</span> <span class="pl-c1">=</span> <span class="pl-s1">numpy</span>.<span class="pl-en">array</span>([[<span class="pl-c1">1</span>, <span class="pl-c1">1</span>, <span class="pl-c1">0</span>], [<span class="pl-c1">1</span>, <span class="pl-c1">1</span>, <span class="pl-c1">1</span>]], <span class="pl-s1">dtype</span><span class="pl-c1">=</span><span class="pl-s1">numpy</span>.<span class="pl-s1">uint8</span>)
<span class="pl-s1">targets</span> <span class="pl-c1">=</span> <span class="pl-s1">numpy</span>.<span class="pl-en">array</span>([[<span class="pl-c1">1</span>, <span class="pl-c1">1</span>, <span class="pl-c1">1</span>], [<span class="pl-c1">0</span>, <span class="pl-c1">0</span>, <span class="pl-c1">0</span>]], <span class="pl-s1">dtype</span><span class="pl-c1">=</span><span class="pl-s1">numpy</span>.<span class="pl-s1">uint8</span>)
<span class="pl-k">for</span> <span class="pl-s1">si</span>, <span class="pl-s1">source</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">sources</span>):
    <span class="pl-k">for</span> <span class="pl-s1">ti</span>, <span class="pl-s1">target</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">targets</span>):
        <span class="pl-en">print</span>(<span class="pl-s">'%d -&gt; %d: %d'</span> <span class="pl-c1">%</span> (<span class="pl-s1">si</span>, <span class="pl-s1">ti</span>, <span class="pl-s1">cv2</span>.<span class="pl-en">norm</span>(<span class="pl-s1">source</span>, <span class="pl-s1">target</span>, <span class="pl-s1">cv2</span>.<span class="pl-v">NORM_HAMMING</span>)))

<span class="pl-s1">bf</span> <span class="pl-c1">=</span> <span class="pl-s1">cv2</span>.<span class="pl-v">BFMatcher</span>(<span class="pl-s1">cv2</span>.<span class="pl-v">NORM_HAMMING</span>, <span class="pl-s1">crossCheck</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)
<span class="pl-s1">matches</span> <span class="pl-c1">=</span> <span class="pl-s1">bf</span>.<span class="pl-en">knnMatch</span>(<span class="pl-s1">sources</span>, <span class="pl-s1">targets</span>, <span class="pl-s1">k</span><span class="pl-c1">=</span><span class="pl-c1">1</span>)
<span class="pl-en">print</span>(<span class="pl-s">'-- crosscheck=True'</span>)
<span class="pl-k">for</span> <span class="pl-s1">match</span> <span class="pl-c1">in</span> <span class="pl-s1">matches</span>:
    <span class="pl-k">if</span> <span class="pl-s1">match</span>:
        <span class="pl-en">print</span>(<span class="pl-s">'%d -&gt; %d: %f'</span> <span class="pl-c1">%</span> (<span class="pl-s1">match</span>[<span class="pl-c1">0</span>].<span class="pl-s1">queryIdx</span>, <span class="pl-s1">match</span>[<span class="pl-c1">0</span>].<span class="pl-s1">trainIdx</span>, <span class="pl-s1">match</span>[<span class="pl-c1">0</span>].<span class="pl-s1">distance</span>))

<span class="pl-s1">bf_nocc</span> <span class="pl-c1">=</span> <span class="pl-s1">cv2</span>.<span class="pl-v">BFMatcher</span>(<span class="pl-s1">cv2</span>.<span class="pl-v">NORM_HAMMING</span>, <span class="pl-s1">crossCheck</span><span class="pl-c1">=</span><span class="pl-c1">False</span>)
<span class="pl-s1">matches_nocc</span> <span class="pl-c1">=</span> <span class="pl-s1">bf</span>.<span class="pl-en">knnMatch</span>(<span class="pl-s1">sources</span>, <span class="pl-s1">targets</span>, <span class="pl-s1">k</span><span class="pl-c1">=</span><span class="pl-c1">1</span>)
<span class="pl-en">print</span>(<span class="pl-s">'-- crosscheck=False'</span>)
<span class="pl-k">for</span> <span class="pl-s1">match</span> <span class="pl-c1">in</span> <span class="pl-s1">matches_nocc</span>:
    <span class="pl-k">if</span> <span class="pl-s1">match</span>:
        <span class="pl-en">print</span>(<span class="pl-s">'%d -&gt; %d: %f'</span> <span class="pl-c1">%</span> (<span class="pl-s1">match</span>[<span class="pl-c1">0</span>].<span class="pl-s1">queryIdx</span>, <span class="pl-s1">match</span>[<span class="pl-c1">0</span>].<span class="pl-s1">trainIdx</span>, <span class="pl-s1">match</span>[<span class="pl-c1">0</span>].<span class="pl-s1">distance</span>))</pre></div>
<p dir="auto">This outputs</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="0 -&gt; 0: 1
0 -&gt; 1: 2
1 -&gt; 0: 0
1 -&gt; 1: 3
-- crossCheck=True
0 -&gt; 1: 2.000000 &lt;= Unexpected
1 -&gt; 0: 0.000000
-- crossCheck=False
0 -&gt; 0: 1.000000
1 -&gt; 0: 0.000000"><pre class="notranslate"><code class="notranslate">0 -&gt; 0: 1
0 -&gt; 1: 2
1 -&gt; 0: 0
1 -&gt; 1: 3
-- crossCheck=True
0 -&gt; 1: 2.000000 &lt;= Unexpected
1 -&gt; 0: 0.000000
-- crossCheck=False
0 -&gt; 0: 1.000000
1 -&gt; 0: 0.000000
</code></pre></div>
<p dir="auto">Here, the 0 -&gt; 1 match when crossCheck=True is unexpected since source 0 is closer to target 0.</p>
<p dir="auto">Also, if we switch the sources and targets arrays, we get</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="0 -&gt; 0: 1
0 -&gt; 1: 0
1 -&gt; 0: 2
1 -&gt; 1: 3
-- crossCheck=True
0 -&gt; 1: 0.000000
-- crossCheck=False
0 -&gt; 1: 0.000000
1 -&gt; 0: 2.000000"><pre class="notranslate"><code class="notranslate">0 -&gt; 0: 1
0 -&gt; 1: 0
1 -&gt; 0: 2
1 -&gt; 1: 3
-- crossCheck=True
0 -&gt; 1: 0.000000
-- crossCheck=False
0 -&gt; 1: 0.000000
1 -&gt; 0: 2.000000
</code></pre></div>
<p dir="auto">Which is correct for crossCheck=True (as well as for crossCheck=False which I don't expect to be symmetrical).</p>
<p dir="auto">Unless I have misunderstood how cross check is supposed to work, this appears to me to be an issue with the current implementation (there has been no updates on this algorithm since 3.4.0 as far as I can see)</p>
<p dir="auto">For C++ sample code, see <a href="http://answers.opencv.org/question/194661/bfmatcher-with-crosscheck-doesnt-crosscheck/" rel="nofollow">http://answers.opencv.org/question/194661/bfmatcher-with-crosscheck-doesnt-crosscheck/</a></p>
<p dir="auto">I am trying to install opencv on my mac<br>
<code class="notranslate"> cd ~/opencv mkdir release cd release cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local .. make</code></p>
<p dir="auto">I get the following error,<br>
<code class="notranslate"> ld: framework not found CoreImage clang: error: linker command failed with exit code 1 (use -v to see invocation) make[2]: * [lib/libopencv_videoio.3.1.0.dylib] Error 1 make[1]: [modules/videoio/CMakeFiles/opencv_videoio.dir/all] Error 2 make: ** [all] Error 2</code></p>