{"cells":[{"metadata":{"_uuid":"76eec8a6-373b-427f-9fbc-5b33b5f57114","_cell_guid":"7c050b9e-89dd-4d7f-9bd4-6c0e36f56209","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n# import os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2e48cf9b-f52d-4bd4-9182-047b6e2548df","_cell_guid":"28296eab-da68-4b3b-bbec-edaab6e7da13","trusted":true},"cell_type":"code","source":"# 对单张图片的变换操作\n# 此代码无需使用TPU/GPU加速\n# 复制全部内容粘贴到kaggle的code代码块即可运行\n\n# 此区域为import和一些需要调用到的函数，  无视即可\nimport random, re, math, time\nimport cv2\nimport numpy as np, pandas as pd\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import KFold\nfrom sklearn.metrics import f1_score, precision_score, recall_score, confusion_matrix\nimport tensorflow as tf, tensorflow.keras.backend as K\nfrom tensorflow.keras.applications import DenseNet201\nfrom kaggle_datasets import KaggleDatasets\n\ndef get_training_dataset(dataset,do_aug=True):\n    dataset = dataset.map(data_augment, num_parallel_calls=AUTO)\n    if do_aug: dataset = dataset.map(transform, num_parallel_calls=AUTO)\n    dataset = dataset.repeat() # the training dataset must repeat for several epochs\n    dataset = dataset.shuffle(2048)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO) # prefetch next batch while training (autotune prefetch buffer size)\n    return dataset\n\ndef load_dataset(filenames, labeled = True, ordered = False):\n    # Read from TFRecords. For optimal performance, reading from multiple files at once and\n    # Diregarding data order. Order does not matter since we will be shuffling the data anyway\n    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False # disable order, increase speed\n        \n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads = AUTO) # automatically interleaves reads from multiple files\n    dataset = dataset.with_options(ignore_order) # use data as soon as it streams in, rather than in its original order\n    dataset = dataset.map(read_labeled_tfrecord if labeled else read_unlabeled_tfrecord, num_parallel_calls = AUTO) # returns a dataset of (image, label) pairs if labeled = True or (image, id) pair if labeld = False\n    return dataset\n\ndef read_labeled_tfrecord(example):\n    LABELED_TFREC_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], tf.string), # tf.string means bytestring\n        \"class\": tf.io.FixedLenFeature([], tf.int64),  # shape [] means single element\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n    image = decode_image(example['image'])\n    label = tf.cast(example['class'], tf.int32)\n    return image, label # returns a dataset of (image, label) pairs\n\ndef decode_image(image_data):\n    image = tf.image.decode_jpeg(image_data, channels=3)\n    image = tf.cast(image, tf.float32) / 255.0  # convert image to floats in [0, 1] range\n    image = tf.reshape(image, [*IMAGE_SIZE, 3]) # explicit size needed for TPU\n    return image\n\n\ndef data_augment(image, label):\n    # data augmentation. Thanks to the dataset.prefetch(AUTO) statement in the next function (below),\n    # this happens essentially for free on TPU. Data pipeline code is executed on the \"CPU\" part\n    # of the TPU while the TPU itself is computing gradients.\n    image = tf.image.random_flip_left_right(image)\n    return image, label \n\n# 定义变量   此处可无视\nif __name__ == \"__main__\":\n    AUTO = tf.data.experimental.AUTOTUNE\n    BATCH_SIZE = 16\n\n# 载入图片   此处可无视\nif __name__ == \"__main__\":\n    IMAGE_SIZE = [512,512]\n    print('Accessing Data: '+time.strftime(\"%Y-%m-%d-%H_%M_%S\", time.localtime()))\n    GCS_DS_PATH = KaggleDatasets().get_gcs_path('tpu-getting-started')\n    # available image sizes :\n    GCS_PATH_SELECT = { \n        192: GCS_DS_PATH + '/tfrecords-jpeg-192x192',\n        224: GCS_DS_PATH + '/tfrecords-jpeg-224x224',\n        331: GCS_DS_PATH + '/tfrecords-jpeg-331x331',\n        512: GCS_DS_PATH + '/tfrecords-jpeg-512x512' \n    }\n    GCS_PATH = GCS_PATH_SELECT[IMAGE_SIZE[0]]\n    TRAINING_FILENAMES = tf.io.gfile.glob(GCS_PATH + '/train/*.tfrec') + tf.io.gfile.glob(GCS_PATH + '/val/*.tfrec')\n    # predictions on this dataset should be submitted for the competition\n    TEST_FILENAMES = tf.io.gfile.glob(GCS_PATH + '/test/*.tfrec')\n    TRAINING_FILENAMES =[TRAINING_FILENAMES[0]]\n\n    \n########################## 以上代码全部无视即可，但是需保留 ##########################","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c2617030-e45c-405e-9142-ad2a7c078e3a","_cell_guid":"ecc7ebb9-1a4c-46f2-8f1c-aeb05549201c","trusted":true},"cell_type":"code","source":"# 提取单张图片   # 此段只需注意图片为遍历变量img即可\nif __name__ == \"__main__\":\n    all_elements = get_training_dataset(load_dataset(TRAINING_FILENAMES),do_aug=False).unbatch();# 下载数据\n    # 提取图片: img \n    for (img,label) in all_elements: # 此处all_elements为list，不可索引（all_elements[0]不可行）\n        plt.figure() # 创建画布\n        plt.imshow(img) # 将img打印到画布\n        print(type(img))\n        print(type(np.array(img)))\n        plt.show() # 显示画布\n        break","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3a1064a1-cc95-4592-989a-b975ef9882ed","_cell_guid":"20abe715-a264-4ac6-b8a6-145ecc8651e4","trusted":true},"cell_type":"code","source":"# 对图片信息的数学操作\n# if __name__ == \"__main__\":\n#     img_changed = (2.1*img) # img*x： 若(x>1) 将提高img亮度\n    \n# 对图片进行有意义的预处理\n#if __name__ == \"__main__\":\n    \n########预处理函数#########\n\n# 添加高斯噪声用于单通道图片：mean均值，var方差\n# 测试用，可忽略\n# def Gauss_noise_gray(img_file1, mean, var):\n#     #image = cv2.imread(img_file1, cv2.IMREAD_GRAYSCALE)\n#     print(\"高斯噪声图\")\n#     img = img_file1\n#     img = np.array(img/255, dtype=float)\n#     noise = np.random.normal(mean, var ** 0.5, img.shape)\n#     out = img + noise\n#     if out.min() < 0:\n#         low_clip = -1.\n#     else:\n#         low_clip = 0.\n#     out = np.clip(out, low_clip, 1.0)\n#     out = np.uint8(out*255)\n#     #cv2.imwrite(out_file, out)\n#     return out\n\n# 添加高斯噪声用于RGB图片，sigma(float,0~100)为噪声比例\n# 我们的data图太小了512size建议0~0.1，否则严重破坏信息，192size几乎不能添加\ndef Gauss_noise_rgb(img_file1,sigma):\n    temp_img = np.float64(np.copy(img_file1))\n    h = temp_img.shape[0]\n    w = temp_img.shape[1]\n    noise = np.random.randn(h,w) * sigma\n    print(\"高斯噪声图\")\n    print(\"噪声数量=\",int(len(noise)))\n    noisy_img = np.zeros(temp_img.shape, np.float64)\n    if len(temp_img.shape) == 2:\n        noisy_img = temp_img + noise\n    else:\n        noisy_img[:,:,0] = temp_img[:,:,0] + noise\n        noisy_img[:,:,1] = temp_img[:,:,1] + noise\n        noisy_img[:,:,2] = temp_img[:,:,2] + noise\n    return noisy_img\n\n# 添加随机椒盐噪声，prob:噪声比例 \ndef sp_noiseImg(img_file1,prob): #同时加杂乱(RGB单噪声)RGB图噪声 prob:噪声占比\n    img = np.array(img_file1,dtype=float)\n    height = img.shape[0]\n    width = img.shape[1]\n    channels = img.shape[2]\n    # prob = 0.05 #噪声占比 已经比较明显了 太大会严重破坏信息\n    # 512size训练建议0.02~0.1，越大处理速度越慢，要注意。192size不要超过0.04\n    NoiseImg = img.copy()\n    NoiseNum = int(prob * img.shape[0] * img.shape[1])\n    print(\"椒盐噪声图\")\n    print(\"噪声数量=\",NoiseNum)\n    for i in range(NoiseNum):    \n        rows = np.random.randint(0, img.shape[0] - 1)    \n        cols = np.random.randint(0, img.shape[1] - 1)    \n        channel = np.random.randint(0, 3)    \n        if np.random.randint(0, 2) == 0:# 随机加盐或者加椒        \n            NoiseImg[rows, cols, channel] = 0    \n        else:        \n            NoiseImg[rows, cols, channel] = 255\n    return NoiseImg\n\n# 随机角度旋转样本，ra旋转角度（默认0~90随机）\ndef rotationImg(img_file1,ra):\n    # 获取图片尺寸并计算图片中心点\n    #img = cv2.imread(img_file1, cv2.IMREAD_GRAYSCALE)\n    print(\"旋转图像\")\n    img = np.array(img_file1,dtype=float)\n    (h, w) = img.shape[:2]\n    center = (w/2, h/2)\n    ra=np.random.randint(0,90)\n    print(\"旋转角度=\",ra)\n    M = cv2.getRotationMatrix2D(center, ra, 1.0)#第三个参数缩放比例\n    rotated = cv2.warpAffine(img, M, (w, h),borderMode=cv2.BORDER_REFLECT_101)#最后一个参数边界填充模式\n    '''\n    填充模式参数：\n    BORDER_CONSTANT #恒像素值填充（有黑边）\n\n    BORDER_REPLICATE #边界像素值填充（这个和参考代码中用到的类似）\n\n    BORDER_REFLECT #翻转像素值填充（推荐）\n\n    BORDER_WRAP #对称像素值填充（相当于平铺，不推荐）\n\n    BORDER_REFLECT_101 #翻转像素值（去掉边界值）填充（推荐）\n\n    BORDER_TRANSPARENT #透明填充（黑边）\n    '''\n    #cv2.imshow(\"rotated\", rotated)\n    #cv2.waitKey(0)\n    #cv2.imwrite(out_file, rotated)\n\n    return rotated\n\n# 随机改变对比度与亮度\n# alpha:原图的权重,beta:叠加层的权重,gamma:亮度（范围-1到1，-1为全黑，1为全白）\ndef contrastImg(img_file1,alpha,beta,gamma):\n    img = np.array(img_file1,dtype=float)\n    alpha,gamma=np.random.uniform(0.7,1.0),np.random.uniform(-0.4,0.4)\n    beta=1.0-alpha\n    img2 =  np.zeros([img.shape[0],img.shape[1],img.shape[2]],img.dtype)\n    print(\"原图权重=\",alpha)\n    contrasted = cv2.addWeighted(img,alpha,img2,beta,gamma)\n    \n    return contrasted\n    \n# 对不同的图片进行不同处理也是可行的，但是需要你给出判断条件，我将用其筛选数据并完成你想要的操作\n\n# 预处理部分&显示图片\nif __name__ == \"__main__\":\n    plt.figure() # 创建画布\n    img_changed=img\n    ########预处理4种方案########测试单独效果=取消单行注释#########\n    '''img_changed=Gauss_noise_gray(img,mean=0,var=5.0e-7)#添加随机高斯噪声(测试用)'''\n    \n    #img_changed=Gauss_noise_rgb(img,sigma=0.2)            #1添加高斯噪声\n    #img_changed=sp_noiseImg(img,prob=0.1)                 #2添加随机椒盐噪声\n    #img_changed=rotationImg(img,ra=0)                     #3随机角度（0-90）旋转图片，可以修改边界填充模式\n    #img_changed=contrastImg(img,alpha=1,beta=0,gamma=0)   #4随机调整对比度与亮度\n    \n    ########显示处理效果#########\n    plt.imshow(img_changed) # 将img打印到画布\n    plt.show() # 显示画布\n    \n# 输入训练\nif __name__ == \"__main__\":\n    # 方法已知，无需在此书写\n    print('示例程序结束')","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}