diff --git a/modules/aruco/include/opencv2/aruco/dictionary.hpp b/modules/aruco/include/opencv2/aruco/dictionary.hpp
index 06602a40b..4a6ce72e4 100644
--- a/modules/aruco/include/opencv2/aruco/dictionary.hpp
+++ b/modules/aruco/include/opencv2/aruco/dictionary.hpp
@@ -84,14 +84,14 @@ class CV_EXPORTS_W Dictionary {
     /**
      * @see generateCustomDictionary
      */
-    CV_WRAP_AS(create) static Ptr<Dictionary> create(int nMarkers, int markerSize);
+    CV_WRAP_AS(create) static Ptr<Dictionary> create(int nMarkers, int markerSize, int randomSeed=0);
 
 
     /**
      * @see generateCustomDictionary
      */
     CV_WRAP_AS(create_from) static Ptr<Dictionary> create(int nMarkers, int markerSize,
-            const Ptr<Dictionary> &baseDictionary);
+            const Ptr<Dictionary> &baseDictionary, int randomSeed=0);
 
     /**
      * @see getPredefinedDictionary
@@ -176,7 +176,8 @@ CV_EXPORTS_W Ptr<Dictionary> getPredefinedDictionary(int dict);
   */
 CV_EXPORTS_AS(custom_dictionary) Ptr<Dictionary> generateCustomDictionary(
         int nMarkers,
-        int markerSize);
+        int markerSize,
+        int randomSeed=0);
 
 
 /**
@@ -185,6 +186,7 @@ CV_EXPORTS_AS(custom_dictionary) Ptr<Dictionary> generateCustomDictionary(
   * @param nMarkers number of markers in the dictionary
   * @param markerSize number of bits per dimension of each markers
   * @param baseDictionary Include the markers in this dictionary at the beginning (optional)
+  * @param randomSeed a user supplied seed for theRNG()
   *
   * This function creates a new dictionary composed by nMarkers markers and each markers composed
   * by markerSize x markerSize bits. If baseDictionary is provided, its markers are directly
@@ -194,7 +196,8 @@ CV_EXPORTS_AS(custom_dictionary) Ptr<Dictionary> generateCustomDictionary(
 CV_EXPORTS_AS(custom_dictionary_from) Ptr<Dictionary> generateCustomDictionary(
         int nMarkers,
         int markerSize,
-        const Ptr<Dictionary> &baseDictionary);
+        const Ptr<Dictionary> &baseDictionary,
+        int randomSeed=0);
 
 
 
diff --git a/modules/aruco/src/dictionary.cpp b/modules/aruco/src/dictionary.cpp
index 207ae6fb0..5a6d0bf5b 100644
--- a/modules/aruco/src/dictionary.cpp
+++ b/modules/aruco/src/dictionary.cpp
@@ -69,17 +69,18 @@ Dictionary::Dictionary(const Mat &_bytesList, int _markerSize, int _maxcorr) {
 
 /**
  */
-Ptr<Dictionary> Dictionary::create(int nMarkers, int markerSize) {
+Ptr<Dictionary> Dictionary::create(int nMarkers, int markerSize, int randomSeed) {
     const Ptr<Dictionary> baseDictionary = makePtr<Dictionary>();
-    return create(nMarkers, markerSize, baseDictionary);
+    return create(nMarkers, markerSize, baseDictionary, randomSeed);
 }
 
 
 /**
  */
 Ptr<Dictionary> Dictionary::create(int nMarkers, int markerSize,
-                                   const Ptr<Dictionary> &baseDictionary) {
-    return generateCustomDictionary(nMarkers, markerSize, baseDictionary);
+                                   const Ptr<Dictionary> &baseDictionary, int randomSeed) {
+
+    return generateCustomDictionary(nMarkers, markerSize, baseDictionary, randomSeed);
 }
 
 
@@ -346,11 +347,11 @@ Ptr<Dictionary> getPredefinedDictionary(int dict) {
 /**
  * @brief Generates a random marker Mat of size markerSize x markerSize
  */
-static Mat _generateRandomMarker(int markerSize) {
+static Mat _generateRandomMarker(int markerSize, RNG &rng) {
     Mat marker(markerSize, markerSize, CV_8UC1, Scalar::all(0));
     for(int i = 0; i < markerSize; i++) {
         for(int j = 0; j < markerSize; j++) {
-            unsigned char bit = (unsigned char) (rand() % 2);
+            unsigned char bit = (unsigned char) (rng.uniform(0,2));
             marker.at< unsigned char >(i, j) = bit;
         }
     }
@@ -377,7 +378,8 @@ static int _getSelfDistance(const Mat &marker) {
 /**
  */
 Ptr<Dictionary> generateCustomDictionary(int nMarkers, int markerSize,
-                                         const Ptr<Dictionary> &baseDictionary) {
+                                         const Ptr<Dictionary> &baseDictionary, int randomSeed) {
+    RNG rng((uint64)(randomSeed));
 
     Ptr<Dictionary> out = makePtr<Dictionary>();
     out->markerSize = markerSize;
@@ -415,7 +417,7 @@ Ptr<Dictionary> generateCustomDictionary(int nMarkers, int markerSize,
     int unproductiveIterations = 0;
 
     while(out->bytesList.rows < nMarkers) {
-        Mat currentMarker = _generateRandomMarker(markerSize);
+        Mat currentMarker = _generateRandomMarker(markerSize, rng);
 
         int selfDistance = _getSelfDistance(currentMarker);
         int minDistance = selfDistance;
@@ -467,9 +469,9 @@ Ptr<Dictionary> generateCustomDictionary(int nMarkers, int markerSize,
 
 /**
  */
-Ptr<Dictionary> generateCustomDictionary(int nMarkers, int markerSize) {
+Ptr<Dictionary> generateCustomDictionary(int nMarkers, int markerSize, int randomSeed) {
     Ptr<Dictionary> baseDictionary = makePtr<Dictionary>();
-    return generateCustomDictionary(nMarkers, markerSize, baseDictionary);
+    return generateCustomDictionary(nMarkers, markerSize, baseDictionary, randomSeed);
 }