{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":19991,"databundleVersionId":1117522,"sourceType":"competition"}],"dockerImageVersionId":31260,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# =================================================\n# INSTALL\n# =================================================\n!pip install opencv-python tqdm numpy\n\n# =================================================\n# IMPORTS\n# =================================================\nimport os\nimport cv2\nimport numpy as np\nfrom tqdm import tqdm\n\n# =================================================\n# PATHS\n# =================================================\nCOVER_FOLDER = \"/kaggle/input/competitions/alaska2-image-steganalysis/Cover\"\nFINAL_FOLDER = \"/kaggle/working/final_filtered\"\nos.makedirs(FINAL_FOLDER, exist_ok=True)\n\n# =================================================\n# DCT FILTER SETTINGS\n# =================================================\nBLOCK_SIZE = 8\nMID_FREQ_THRESHOLD =5       # very low threshold\nMIN_GOOD_BLOCK_RATIO =1  # only 5% of blocks need to pass\n\nJPEG_Q = np.array([\n    [16,11,10,16,24,40,51,61],\n    [12,12,14,19,26,58,60,55],\n    [14,13,16,24,40,57,69,56],\n    [14,17,22,29,51,87,80,62],\n    [18,22,37,56,68,109,103,77],\n    [24,35,55,64,81,104,113,92],\n    [49,64,78,87,103,121,120,101],\n    [72,92,95,98,112,100,103,99]\n])\n\nEMBED_POS = [\n    (2,3),(3,2),(1,4),(4,1),(2,4),(4,2),\n    (3,3),(1,5),(5,1),(2,5),(5,2),\n    (3,4),(4,3),(2,6),(6,2),(3,5),(5,3)\n]\n\n# =================================================\n# BLOCKIFY FUNCTION\n# =================================================\ndef blockify(channel):\n    h, w = channel.shape\n    blocks = []\n    for i in range(0, h-BLOCK_SIZE+1, BLOCK_SIZE):\n        for j in range(0, w-BLOCK_SIZE+1, BLOCK_SIZE):\n            blocks.append(channel[i:i+BLOCK_SIZE, j:j+BLOCK_SIZE])\n    return blocks\n\n# =================================================\n# MID FREQUENCY SCORE FUNCTION\n# =================================================\ndef midfreq_score(block):\n    dct = cv2.dct(block.astype(np.float32))\n    q = np.round(dct / JPEG_Q)\n    score = 0\n    for (i,j) in EMBED_POS:\n        if abs(q[i,j]) >= 1:\n            score += 1\n    return score\n\n# =================================================\n# RUN FILTER\n# =================================================\ncover_files = os.listdir(COVER_FOLDER)\n# cover_files = cover_files[35000:]\nprint(\"Total cover images found:\", len(cover_files))\n\nsaved_count = 0\n\nfor file in tqdm(cover_files):\n    try:\n        img_path = os.path.join(COVER_FOLDER, file)\n        img = cv2.imread(img_path)\n\n        if img is None:\n            continue\n\n        # Convert to Y channel\n        ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)\n        Y = ycrcb[:,:,0]\n\n        # Blockify and calculate mid-frequency scores\n        blocks = blockify(Y)\n        good = sum(midfreq_score(b) >= MID_FREQ_THRESHOLD for b in blocks)\n\n        # DEBUG: print first few images\n        if saved_count < 5:\n            print(f\"{file}: good_blocks={good}, total_blocks={len(blocks)}, ratio={good/len(blocks):.3f}\")\n\n        # Keep image if enough blocks pass\n        if good > len(blocks) * MIN_GOOD_BLOCK_RATIO:\n            cv2.imwrite(os.path.join(FINAL_FOLDER, file), img)\n            saved_count += 1\n\n    except Exception as e:\n        print(f\"Error processing {file}: {e}\")\n        continue\n\nprint(\"Filtering Done!\")\nprint(\"Final dataset size (images saved):\", saved_count)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-10T17:45:21.081384Z","iopub.execute_input":"2026-02-10T17:45:21.082011Z","iopub.status.idle":"2026-02-10T17:47:57.867468Z","shell.execute_reply.started":"2026-02-10T17:45:21.081975Z","shell.execute_reply":"2026-02-10T17:47:57.866289Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import shutil\n\nfolder_to_zip = FINAL_FOLDER\nzip_output_path = \"/kaggle/working/final_filtered.zip\"\n\n# Zip the folder\nshutil.make_archive(base_name=zip_output_path.replace('.zip',''), \n                    format='zip', \n                    root_dir=folder_to_zip)\n\n# Move to output folder\nos.makedirs(\"/kaggle/output\", exist_ok=True)\nshutil.copy(zip_output_path, \"/kaggle/output/final_filtered.zip\")\n\nprint(\"Zipped folder moved to Kaggle output! You can download from the Output tab now.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-10T17:48:43.402930Z","iopub.execute_input":"2026-02-10T17:48:43.403603Z","iopub.status.idle":"2026-02-10T17:48:43.409279Z","shell.execute_reply.started":"2026-02-10T17:48:43.403570Z","shell.execute_reply":"2026-02-10T17:48:43.408641Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch #This is PyTorch, the engine that handles the tensors (matrices) and the GPU math.\nfrom PIL import Image\nfrom diffusers import StableDiffusionPipeline \n#It’s a class that knows how to connect the 3 main models (VAE, U-Net, Text Encoder) so they can talk to each other in the right order.\nmodel_id=\"runwayml/stable-diffusion-v1-5\"\npipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16)\n#from_pretrained: This command downloads (or loads from cache) about 5GB of data. It doesn't just load one model; it loads an entire folder of sub-models (the tokenizer, the scheduler, the text encoder, etc.).\npipe = pipe.to(\"cuda\") #gpu laoding\nprompt=\" A black cat eating fish\"\nimage=pipe(prompt).images[0]\nimport matplotlib.pyplot as plt\n\nplt.imshow(image)\nplt.title(f\"Prompt: {prompt}\")\nplt.axis(\"off\") # Hide the x/y coordinates\nplt.show()\n\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-02-10T17:45:19.129238Z","iopub.status.idle":"2026-02-10T17:45:19.129794Z","shell.execute_reply.started":"2026-02-10T17:45:19.129608Z","shell.execute_reply":"2026-02-10T17:45:19.129631Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}