title: Invalid number of channels in input image error using OpenCV
body: <pre><code>cv2.error: OpenCV(4.2.0) c:\projects\opencv
  python\opencv\modules\imgproc\src\color.simd_helpers.hpp:92: error:
  (-2:Unspecified error) in function '__cdecl cv::impl::`anonymous- 
  </code></pre>
  <p>namespace'::CvtHelper&lt;struct cv::impl::`anonymous<br />
  namespace'::Set&lt;3,4,-1&gt;,struct cv::impl::A0xe227985e::Set&lt;1,-1,-1&gt;,struct
  cv::impl::A0xe227985e::Set&lt;0,2,5&gt;,2&gt;::CvtHelper(const class
  cv::_InputArray<code> </code>&amp;,const class cv::_OutputArray &amp;,int)
  &gt; Invalid number of channels in input image:
  &gt;     'VScn::contains(scn)'
  &gt; where
  &gt;     'scn' is 1</p>
  <pre><code>img = cv2.cvtColor(images, cv2.COLOR_BGR2GRAY) 
  </code></pre>
  <p>this line gives me error</p>
  <p>hello everyone i am new to use opencv, now i am doing project on image classification</p>
  <p>my complete code as follows</p>
  <pre><code>from flask import Flask, request
  from flask_restful import Api, Resource
  import sys, os
  from myconstants1 import path_logs, path_resources
  from logConfig1 import setup_logger
  import pathlib, pycountry, cv2, pickle, random, PIL, sys
  from pathlib import Path 
  import pathlib as pl
  import numpy as np
  from sklearn.model_selection import train_test_split
  import pandas as pd
  import matplotlib.pyplot as plt
  from keras.models import Sequential
  from keras.layers import Dense
  from keras.optimizers import Adam
  from keras.utils.np_utils import to_categorical
  from keras.layers import Flatten, Dropout
  from keras.layers.convolutional import Conv2D, MaxPooling2D
  from keras.preprocessing.image import ImageDataGenerator
  from PIL import Image, ImageOps
  os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
  
  logger = setup_logger('/modelTrain', path_logs+'/modelTrain.log')
  
  app = Flask(__name__)
  api = Api(app)
  
  path = sys.path
  path = Path(__file__).parent
  
  print(&quot;path2&quot;, path)
  
  class HandleRequest5(Resource):
      y_validation = &quot;&quot;
      x_test = &quot;&quot;
      x_validation  = &quot;&quot;
      x_train = &quot;&quot;
           
      @classmethod
      def post(cls, json): 
                 
          data = request.get_json()
          
          json = ({
              &quot;Status&quot;: &quot;failed&quot;,
              &quot;message&quot;: &quot;ALL fields are mandatory&quot;
                  })
                  
          try:
              country_code = data[&quot;country_code&quot;].upper()  
              batch_size = data[&quot;batch_size&quot;]
              step_per_epoch_val = data[&quot;step_per_epoch_val&quot;]
              epoch = data[&quot;epoch&quot;]
          except KeyError:
              print(json)
              logger.debug(json)
              return(json)
  
          
          try:
              country = pycountry.countries.get(alpha_3 = data[&quot;country_code&quot;].upper()).name.lower()
              print(&quot;country1&quot;, country)
              logger.debug(f'country1 : {country}')
              country = country.split()
              country =(&quot;_&quot;.join(country))
              print(&quot;country : &quot;, country)
              logger.debug(f&quot;country : {country}&quot;)
              alpha_2 = pycountry.countries.get(alpha_3 = data[&quot;country_code&quot;].upper()).alpha_2
              print(&quot;alpha_2 : &quot;, alpha_2)
              logger.debug(f&quot;alpha_2 : {alpha_2}&quot;)
          except AttributeError:                
              jsonify1 = {
                          &quot;status&quot;: &quot;invalid&quot;,
                          &quot;message&quot; : &quot;Invalid country_code&quot;
                          }
              print(&quot;invalid country_code&quot;)
              
              logger.debug({
                          &quot;status&quot;: &quot;invalid&quot;,
                          &quot;message&quot; : &quot;Invalid country_code&quot;
                          })
              return jsonify1
      
      #   path = rf'{path}/{country}'  # folder with all class folders
          
          labelFile = rf'{path_resources}/{country}/labels.csv'         
          imageDimensions = (99, 200, 3)
          print(&quot;imageDimensions:&quot;, imageDimensions)
          testRatio = 0.2               # if 1000 images split will 200 for testing
          validationRatio = 0.2  
          print(&quot;line 91 is going to execute&quot;)
          cls.importImages( cls,testRatio , validationRatio , imageDimensions  ,country , labelFile)   
          
      def importImages(cls, testRatio, validationRatio, imageDimensions, country, labelFile):
          count = 0
          images = []
          classNo = []
          
  
          p = pl.Path(f'{path_resources}/{country}')                    
          mylist = [x for x in p.iterdir() if x.is_dir()]
          print(&quot;mylist1&quot;, mylist)
          print(&quot;total classs detected :&quot;, len(mylist))
          noofClasses = len(mylist)
          print(&quot;noofClasses:&quot;, noofClasses)
          print(&quot;importing classes...&quot;)
          
          for x in range(0, len(mylist)):
  
              myPicList = os.listdir(os.path.join(str(path_resources), str(country)+'//'+str(count))) 
              print(&quot;myPicList1:&quot;, myPicList)
  
              #for y in myPicList:
                  #print(os.path.join(path, str(count), y))
                  #curImg = cv2.imread((str(path_resources)+&quot;/&quot;+str(count)+&quot;//&quot;+y))
                  
              for y in myPicList:
                  print(os.path.join(path_resources, country, str(count)+y))
  
                  curImg = cv2.imread(f&quot;{path_resources}{country}/{str(count)}//{y}&quot;)                                                      
                  images.append(curImg)
                  classNo.append(count)
              print(count, end = &quot; &quot;)
              count+=1
          print(&quot; &quot;)
          images = np.array(images, dtype=np.uint8) 
          images = np.array(images)
          print(&quot;line 128&quot;)
          print(images.shape)
          #images = np.append(images,4)
          #images = images.append((Image.fromarray(images, dtype=np.float32).convert('RGB') / 255.))
  #        image = Image.fromarray(images)
          #images = images.convert(&quot;RGB&quot;)
          classNo = np.array(classNo)        
          
          cls.splitData(cls,images, classNo, testRatio, validationRatio , imageDimensions, labelFile, noofClasses)
          return images, classNo, noofClasses
          
          # split data #
      def splitData(cls, images, classNo, testRatio, validationRatio , imageDimensions, labelFile, noofClasses):
  
          x_train, x_test, y_train, y_test = train_test_split(images, classNo, test_size = testRatio)
          x_train, x_validation, y_train, y_validation = train_test_split(x_train, y_train , test_size = validationRatio)
          
          # to check if no of images matches to number of labels for each data set
          print(&quot;data shapes...&quot;)
          print(&quot;train : &quot;, end = &quot;&quot;);print(x_train.shape, y_train.shape)
          print(&quot;validation :&quot;, end = &quot;&quot;); print(x_validation.shape, y_validation.shape) 
          print(&quot;test :&quot;, end = &quot;&quot;); print(x_test.shape, y_test.shape)        
          
          assert (x_train.shape[0] == y_train.shape[0]),  &quot;the no of images is not equal to the no of labels in training set&quot;
          assert (x_validation.shape[0] == y_validation.shape[0]), &quot;the no of images is not equal to the no of labels in validation set&quot;
          assert (x_test.shape[0] == y_test.shape[0]), &quot;the no of images is not equal to the no of labels in test set&quot;
          #print(x_train.shape)
          assert (x_train.shape[1:]  == (imageDimensions)),  &quot;the dimension of training images are wrong&quot;
          assert (x_validation.shape[1:] == (imageDimensions)), &quot;the dimension of validation images are wrong&quot;
          assert (x_test.shape[1:] == (imageDimensions)), &quot;the dimension of test images are wrong&quot;        
          
          data = pd.read_csv(labelFile) 
          
          cls.grayscale(cls, images, x_train, x_validation, x_test, y_train, y_validation, y_test )
          
          return images, x_train, x_validation, x_test, y_train, y_validation, y_test
          # preprocessing the image #
  
      def grayscale(cls,images, x_train, x_validation, x_test, y_train, y_validation, y_test):
          #images = ImageOps.grayscale(images)
          images = cv2.cvtColor(images, cv2.COLOR_BGR2GRAY)
          cls.equalize(images)
          return images
          
      def equalize(images):
          img = cv2.equalizeHist(images)       
          cls.preprocessing(img, grayscale, equalize)
          return img
          
      def preprocessing(cls, img, grayscale, equalize, x_train, x_validation, x_test, y_train, y_test, y_validation):
          img = grayscale(img)  #convert to grayscale
          img = equalize(img)   #standardize the lightining of an image
          img = img/255         # to normaize value between 0 and 1 instead of 0 to 255
          return img , x_train, x_validation, x_test, y_train, y_test, y_validation
  
          x_train = np.array(list(map(preprocessing, x_train)))  # to iterate and preprocess all images
          x_validation = np.array(list(map(preprocessing, x_validation)))
          x_test = np.array(list(map(preprocessing, x_test)))
  
          #cv2.imshow(&quot;grayscale images&quot;, x_train[random.randint(0, len(x_train)-1)]) #to check if training is done properly
                 
          # add a depth of 1 #
  
          x_train = x_train.reshape(x_train.shape[0], x_train.shape[1], x_train.shape[2], 1)
          x_validation = x_validation.reshape(x_validation .shape[0], x_validation .shape[1], x_validation .shape[2], 1)
          x_test = x_test.reshape(x_test.shape[0], x_test.shape[1], x_test.shape[2], 1)
  
  
      def dataAugmentation(cls, x_train, y_train, noofClasses):
      # augmentation of images to make it more generic #
  
          dataGen = ImageDataGenerator(width_shift_range = 0.1, 
                               height_shift_range  = 0.1,
                               zoom_range = 0.2,
                               shear_range = 0.1,
                               rotation_range = 10)
  
          dataGen.fit(x_train)
          batches = dataGen.flow(x_train, y_train, batch_size = 20)
          x_batch, y_batch = next(batches)
  
  
  # to show augmentated image sample 
  #fig, axs = plt.subplots(24, 2, figsize = (20, 5))
  #fig.tight_layout()
  #print(axs)
  #print(&quot;axs0:&quot;,axs[0])
  #print(&quot;axs1:&quot;,axs[1])
  #for i in range(10):
      #axs[i].imshow(x_batch[i].reshape(imageDimensions[0], imageDimensions[1]))
      #axs[0][1].imshow(x_batch[i].reshape(imageDimensions[0], imageDimensions[1]))
      #axs[i].axis(&quot;off&quot;)
      #axs[0][1].axis('off')
  #plt.show()
  
          y_train = to_categorical(y_train, noofClasses) 
          y_validation = to_categorical(y_validation, noofClasses) 
          y_test = to_categorical(y_test, noofClasses) 
          cls.splitData(y_validations)        
          cls.myModel(noofClasses)
  # convolution neural network #
  
      def myModel(cls, noofClasses, country):
          no_of_filters = 60 
          size_of_filter = (5,5)  #this is kernal that move around the image to get the features 
      
          size_of_filter2 = (3,3) 
          size_of_pool = (2,2)
          no_of_nodes = 200
      
          model = Sequential()
          model.add(Conv2D(no_of_filters, size_of_filter, input_shape = (imageDimensions[0], imageDimensions[1], 1), activation = &quot;relu&quot;))
          model.add(Conv2D(no_of_filters, size_of_filter, activation = &quot;relu&quot;))
          model.add(MaxPooling2D(pool_size = size_of_pool))
      
          model.add(Conv2D(no_of_filters//2, size_of_filter2, activation = &quot;relu&quot;))
          model.add(Conv2D(no_of_filters//2, size_of_filter2, activation = &quot;relu&quot;))
          model.add(Dropout(0.5))
      
          model.add(Flatten())
          model.add(Dense(no_of_nodes, activation = &quot;relu&quot;))
          model.add(Dropout(0.5))
      
      
    #  model.add(Flatten())
          model.add(Dense(noofClasses, activation = &quot;softmax&quot;))
      
      # compile model #
          model.compile(Adam(lr = 0.001), loss = &quot;categorical_crossentropy&quot;,  metrics = [&quot;accuracy&quot;])
          return model    
      
      # train #
          model = myModel()
  
          print(model.summary())
          history = model.fit_generator  (dataGen.flow(x_train, y_train, batch_size = batch_size_val), steps_per_epoch = steps_per_epoch_val, epochs = epoch_val, validation_data = (x_train, y_train))  
          
  # plot #
  
          plt.figure(1)
          plt.plot(history.history[&quot;loss&quot;])
          plt.plot(history.history[&quot;val_loss&quot;])
          plt.legend([&quot;training&quot;, &quot;validation&quot;])
  
          plt.title(&quot;loss&quot;)
          plt.xlabel(&quot;epoch&quot;)
          plt.figure(2)
          plt.plot(history.history[&quot;accuracy&quot;])
          plt.plot(history.history[&quot;val_accuracy&quot;])
  
          plt.legend([&quot;training&quot;, &quot;accuracy&quot;])
          plt.title(&quot;accuracy&quot;)
          plt.xlabel(&quot;epoch&quot;)
          #plt.show()
  
  
          score = model.evaluate(x_test, y_test, verbose = 0)
          print(&quot;test score: &quot;, score[0])
          print(&quot;test accuracy: &quot;, score[1])
  
      ###############################################################
      #store the model as pickle object #
      #save_path = rf'{path}/{country}'
          pickle_out = open(rf&quot;{path_resources}/{country}.p&quot;, &quot;wb&quot;)
      #model = model.save(rf'{country}_{epoch_val}.h5')
  
          pickle.dump(model, pickle_out)
          pickle_out.close()
          print(rf&quot;{country}_model saved...&quot;)
          cv2.waitKey(0)        
  
          
  api.add_resource(HandleRequest5, '/modelTrain')
  if __name__ == ' __main__ ':
      app.run(debug = False)
  </code></pre>